C
C#14mo ago
Aokiri 🐸

Confusion about Repository Pattern and Unit of Work.

Hi there. I recently applied the Repository Pattern and Unit of Work in an API I'm creating, and everything was going well. However, I got stuck trying to understand how to pass the Database Context to the implementation of one of my interfaces. I'm trying to grasp it, but I can't figure it out. I'll attach few code for reference: (Program.cs) Here is where I'll apply Dependency Injection for my ICategoryRepository with a Scoped lifetime:
builder.Services.AddScoped<ICategoryRepository, CategoryRepository>();
builder.Services.AddScoped<ICategoryRepository, CategoryRepository>();
(DataAccess/Repository/Repository.cs) Here is my implementation of my Repository Interface (only constructor and fields):
public class Repository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _db;
internal DbSet<T> dbSet;

public Repository(ApplicationDbContext db)
{
_db = db;
this.dbSet = _db.Set<T>();
// For example, _db.Categories == dbSet
}
public class Repository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _db;
internal DbSet<T> dbSet;

public Repository(ApplicationDbContext db)
{
_db = db;
this.dbSet = _db.Set<T>();
// For example, _db.Categories == dbSet
}
(DataAccess/Repository/CategoryRepository.cs) And here is my implementation of my Category Repository Interface (only constructor, as always):
public class CategoryRepository : Repository<Category>, ICategoryRepository
{
private readonly ApplicationDbContext _db;

public CategoryRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public class CategoryRepository : Repository<Category>, ICategoryRepository
{
private readonly ApplicationDbContext _db;

public CategoryRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
Look how these two has inyected with the DbContext, but here comes my confusion... In the controller, I created an ICategoryRepository object, but I don't understand how it pass the DbContext to the controller itself...
11 Replies
Angius
Angius14mo ago
The controller doesn't need the dbcontext The context gets injected into the repository, the repository gets injected into the controller As long as the dbcontext and the repository are registered in the DI container, it'll just work
Aokiri 🐸
Aokiri 🐸OP14mo ago
What's the DI? And thanks for the answer!
Angius
Angius14mo ago
Dependency Injection The builder.Services.AddSomething<I, T>
Aokiri 🐸
Aokiri 🐸OP14mo ago
Oh, ok. Now I understand. Let me know something about the Unit of Work: how does it exactly works? I did this implementation:
public class UnitOfWork : IUnitOfWork
{
private ApplicationDbContext _db;
public ICategoryRepository Category { get; private set; }

public UnitOfWork(ApplicationDbContext db)
{
_db = db;
Category = new CategoryRepository(_db);
}
public class UnitOfWork : IUnitOfWork
{
private ApplicationDbContext _db;
public ICategoryRepository Category { get; private set; }

public UnitOfWork(ApplicationDbContext db)
{
_db = db;
Category = new CategoryRepository(_db);
}
Just passed the context and generated a new CategoryRepository object with the context as well. Also implemented a Save() method (to save changes to the db)
Angius
Angius14mo ago
Honestly, dunno I never used generic repository pattern, because why would I ever DbContext already implements UoW, so I never saw much point
Aokiri 🐸
Aokiri 🐸OP14mo ago
It is supposed to have certain benefits as well as its drawbacks, but I didn't know that DbContext already comes with UnitOfWork included...
Angius
Angius14mo ago
IME generic repositories are all drawbacks and no benefits But some companies do require it in their codebase, so knowing what it is and how it works is useful ig
Aokiri 🐸
Aokiri 🐸OP14mo ago
Well, I think I'll continue learning these kinds of things in a general sense, at least to understand them... even if I don't end up using them. Thank you very much for the response, really ^^
Omnissiah
Omnissiah14mo ago
i don't think you can really use repository and unit of work together...? with unit of work you would perform the entire "operation", which could theoretically span multiple dbsets so i guess you could internally use every dbset as a repository, but it would be useless
Aokiri 🐸
Aokiri 🐸OP14mo ago
I mainly do it to have cleaner code. Because with the Repository Pattern, even though it has the advantage of decoupling components, in the long run, I'll end up adding about 10 different repositories and having to apply each of them individually. On the other hand, with UnitOfWork, at least I can implement them all within itself and work with it. I know it has the disadvantage that, in the long run, one controller will have things it shouldn't... but at least the advantage is that the code feels cleaner. I'm not sure if this will cause me problems in the future, though...
Omnissiah
Omnissiah14mo ago
dbcontext is already decoupling logic and db implementation; also, even if maybe is not decoupled as much as you want, would you really use/benefit from that level of isolation?
I'm not sure if this will cause me problems
there will always be "problems" to solve if the software continues to evolve, i believe the main decision would be the complexity/size of the software, or chosing the right amount of decoupling based on how much really you would need it with a repository pattern (and no unit of work) you could implement the data layer for a small application (if you say you have only 10 repositories), it wouldn't be as elegant and as easy to use as mediatr, but it could have its place on the other hand it depends also how you use those repositories
Want results from more Discord servers?
Add your server