Search code examples
asp.netmodel-view-controllerentity-framework-coreunit-of-work

Unit of work pattern not allowing me to create db context without options


I am using ef core and I am trying to implement the repository pattern as part of best practices. But I am we bit confused on the context normally I would create the context in the and inject

HomeController(WarehouseDBContext _context)

I have created my unitOfWork Class as suggested by the docs here https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application#creating-the-unit-of-work-class

However I am tad confused. It's expecting options here which is normally handled on the controller.

My UnitOfWork class

public class WarehouseUnitOfWork : IDisposable
{
    private WarehouseDBContext context = new WarehouseDBContext();
    private WarehouseRepository<StockItem> stockRepository;
 

    public WarehouseRepository<StockItem> StockRepoistry
    {
        get
        {

            if (this.stockRepository == null)
            {
                this.stockRepository = new WarehouseRepository<StockItem>(context);
            }
            return stockRepository;
        }
    }
    public void Save()
    {
        context.SaveChanges();
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

But here it is complain that it expect options which would I presume contain the connection string. I am trying to decouple my code from EF so that If I want to upgrade in the future will be easier. My WareshouseDBContext is describe below

As you can see it is expecting options. What should I pass through here?

namespace WareHouseDal.Dal {
 public class WarehouseDBContext : IdentityDbContext<ApplicationUser> {
      public WarehouseDBContext(DbContextOptions<WarehouseDBContext> options)
        : base(options) {
        
    }

    public DbSet<WarehouseCrm> Warehouse { get; set; }
    public DbSet<Company> Companies { get; set; }
 }

}

When I used to create my context before I just used the singleton pattern of

private readonly WarehouseDBContext _context;

Is their something else I need to do to allow it to accept the creation of the context on the unit of work level.

Error being given is

enter image description here


Solution

  • You shouldn't create a DbContext manually. Why not injecting the DbContext in your UOW class? Then the DI will manage the life cycle of the db context. To be honest I am not a fan of adding a UOW wrapper around EF which already implements the UOW pattern.

    I would recommend you to see both talks, it will change the way you structure apps forever:

    https://www.youtube.com/watch?v=5OtUm1BLmG0&ab_channel=NDCConferences

    https://www.youtube.com/watch?v=5kOzZz2vj2o&t=3s&ab_channel=NDCConferences

    Another amazing talk about EF Core details: https://www.youtube.com/watch?v=zySHbwl5IeU&ab_channel=NDCConferences

    If you want to stick with Repository pattern, please check Ardalis repository with a clear example: https://github.com/ardalis/CleanArchitecture