I'm trying to inject TenantProvider into DbContext
public class AppDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, long>
{
public int? _tenantId;
public ITenantProvider _tenantProvider;
public AppDbContext(
DbContextOptions<AppDbContext> options,
ITenantProvider tenantProvider
)
: base(options)
{
_tenantProvider = tenantProvider;
}
but I don't understand how to register it correctly - if I put the breakpoint in the constructor - tenantProvider
is null
.
The bit from Startup.cs
services.AddDbContext<AppDbContext>(options => AppDbContextOptionsBuilder.Get());
the next line is required to inject the DbContext
into a controller or a service (if I add ServiceLifetime.Scoped
as a second parameter to the method above - AddDbContext
- the feature doesn't work):
services.AddScoped(p => new AppDbContext(AppDbContextOptionsBuilder.Get(), p.GetService<ITenantProvider>()));
(Entity Framework
is a separate project in my solution)
When using .AddScoped
method - we can pass TenantProvider
into constructor by resolving it using .GetService
method.
Does anyone have an idea of how to resolve TenantProvider
in .AddDbContext
method?
Additional info:
I was trying to replace ITenantProvider
in the constructor of DbContext
with IHttpContextAccessor
- the latter is registered as singleton. But the acessor
parameter is still null
.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
I don’t really understand what your
AddScoped
call is supposed to do.AddDbContext
will already register the database context properly with the service collection. So when you resolve the context through dependency injection, additional dependencies will be automatically resolved.So it should be enough to do this:
And then, you can depend on your
AppDbContext
using constructor injection, e.g. in your controllers.Two notes though:
When configuring options, you should modify the passed options object. So you should not just return
AppDbContextOptionsBuilder.Get()
but instead use the passed options object and edit that.You should really think about whether your database context having a dependency on your tenant provider is the right thing to do. As per SRP, your database should only do a single thing and that is provide database access.
Depending on how your tenant provider affects your database access, it might make more sense to move this dependency up one level into some service that uses both the database context and the tenant provider to query data in the right way.