Sto cercando di iniettare TenantProvider in 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;
}
ma non capisco come registrarlo correttamente - se inserisco il breakpoint nel costruttore - tenantProvider
è null
.
Il bit da Startup.cs
services.AddDbContext<AppDbContext>(options => AppDbContextOptionsBuilder.Get());
la riga successiva è necessaria per iniettare DbContext
in un controller o un servizio (se aggiungo ServiceLifetime.Scoped
come secondo parametro al metodo precedente - AddDbContext
- la funzionalità non funziona):
services.AddScoped(p => new AppDbContext(AppDbContextOptionsBuilder.Get(), p.GetService<ITenantProvider>()));
( Entity Framework
è un progetto separato nella mia soluzione)
Quando si utilizza il metodo .AddScoped
, possiamo passare a TenantProvider
nel costruttore risolvendolo utilizzando il metodo .GetService
.
Qualcuno ha un'idea di come risolvere TenantProvider
nel metodo .AddDbContext
?
Informazioni addizionali:
Stavo cercando di sostituire ITenantProvider
nel costruttore di DbContext
con IHttpContextAccessor
- quest'ultimo è registrato come singleton. Ma il parametro acessor
è ancora null
.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Non capisco cosa AddScoped
tua chiamata AddScoped
. AddDbContext
registrerà già correttamente il contesto del database con la raccolta di servizi. Pertanto, quando si risolve il contesto tramite l'integrazione delle dipendenze, le dipendenze aggiuntive verranno automaticamente risolte.
Quindi dovrebbe essere sufficiente per fare questo:
services.AddDbContext<AppDbContext>(options => …);
services.AddSingleton<ITenantProvider, TenantProvider>();
E poi, puoi dipendere da AppDbContext
usando l'iniezione del costruttore, ad esempio nei tuoi controller.
Due note però:
Durante la configurazione delle opzioni, è necessario modificare l'oggetto delle opzioni passate. Quindi non dovresti semplicemente restituire AppDbContextOptionsBuilder.Get()
ma invece usare l'oggetto delle opzioni passato e modificarlo.
Dovresti davvero pensare se il tuo contesto di database che ha una dipendenza dal tuo fornitore di tenant è la cosa giusta da fare. Come da SRP , il tuo database dovrebbe fare una sola cosa e fornire accesso al database.
A seconda di come il tuo tenant provider influisce sull'accesso al tuo database, potrebbe essere più sensato spostare questa dipendenza di un livello in un servizio che utilizza sia il contesto del database che il provider del titolare per interrogare i dati nel modo giusto.