Search code examples
c#asp.net-coreasp.net-web-apidependency-injectionunit-of-work

Is it ok to inject both UnitOfWork and DbContext itself?


I am using UnitOfWork pattern and it's working perfectly but as I need to use UserManager and SinginManager I have to add this part to startup.cs as well

        services.AddDbContext<MainDbContext>(p => p.UseSqlServer(
            @"Data Source="));

but since I'm using UnitOfWork I add these line too;

            services.AddScoped<IUnitOfWork<MainDbContext>, UnitOfWork<MainDbContext>>();
        services.AddScoped<IUnitOfWork<FinancialDbContext>, UnitOfWork<FinancialDbContext>>();

Is it OK to inject and active both ways in startup.cs?


Solution

  • The two registrations appear to be related.

    The first

    services.AddDbContext<MainDbContext>(p => p.UseSqlServer(@"Data Source=Main...."));
    

    makes the container aware of how to resolve the context itself when requested,

    while the second registers types that most likely depend on the context

    services.AddScoped<IUnitOfWork<MainDbContext>, UnitOfWork<MainDbContext>>();
    services.AddScoped<IUnitOfWork<FinancialDbContext>, UnitOfWork<FinancialDbContext>>();
    

    The above can also be simplified using open generics to

    services.AddScoped(typeof(IUnitOfWork<>), typeof(UnitOfWork<>));
    

    which tells the container

    "When ever IUnitOfWork<SomeContext> is request, resolve to UnitOfWork<SomeContext>"

    So there is nothing wrong if you require units that use different contexts

    services.AddDbContext<MainDbContext>(p => p.UseSqlServer(@"Data Source=Main....")); 
    services.AddDbContext<FinancialDbContext>(p => p.UseSqlServer(@"Data Source=Financial...."));
    services.AddScoped(typeof(IUnitOfWork<>), typeof(UnitOfWork<>));
    

    With that out of the way, do note that the Entity Framework is already designed around the Unit of Work / Repository pattern with its DbContext and DbSet respectively.