我试图在aspnet核心DI中注册多个DbContext实现。
所以我注册了DbContext,如下图所示。
services.AddScoped(c => new CoreDbContext(c.GetService<DbContextOptions<CoreDbContext>>()));
services.AddScoped(c => new TnADbContext(c.GetService<DbContextOptions<TnADbContext>>()));
services.AddScoped<Func<DbContextType, IDbContext>>(provider => key =>
{
switch (key)
{
case DbContextType.Core:
return provider.GetService<CoreDbContext>();
case DbContextType.TnA:
return provider.GetService<TnADbContext>();
case DbContextType.Payroll:
throw new ArgumentOutOfRangeException(nameof(key), key, null);
default:
throw new ArgumentOutOfRangeException(nameof(key), key, null);
}
});
所以在仓库中,我试图请求如下的实例
private readonly IDbContext _context;
public Repository(Func<DbContextType, IDbContext> resolver)
{
_context = resolver(DbContextType.TnA);
}
但是当我运行这个应用程序时,它却抛出了一个异常,如下所示
有些服务无法被构造(验证服务描述符'ServiceType.TestController'时出错。Web.Area.TestController Lifetime: Transient ImplementationType.Web.Areas.TestController': 在验证服务描述符'ServiceType: Web.Areas.TestController Lifetime: Transient ImplementationType: Web.Areas.TestController"。 当试图激活'Service.InterfaceService'时,无法解析'Data.IDbContext'类型的服务。)
基本上几乎所有的服务和控制器都在抱怨同一个问题。那么缺失的部分是什么呢?
更新
其实我在注册DB上下文时做了一些修改,现在可以了。
services.AddScoped<Func<DbContextType, IDbContext>>(provider => key =>
{
switch (key)
{
case DbContextType.Core:
return new CoreDbContext(provider.GetService<DbContextOptions<CoreDbContext>>());
case DbContextType.TnA:
return new TnADbContext(provider.GetService<DbContextOptions<TnADbContext>>());
case DbContextType.Payroll:
throw new ArgumentOutOfRangeException(nameof(key), key, null);
default:
throw new ArgumentOutOfRangeException(nameof(key), key, null);
}
});
所以我想出了一个解决方案,注册Dbconfigs,如下所示
services.AddScoped<Func<DbContextType, IDbContext>>(provider => key =>
{
switch (key)
{
case DbContextType.Core:
return new CoreDbContext(provider.GetService<DbContextOptions<CoreDbContext>>());
case DbContextType.TnA:
return new TnADbContext(provider.GetService<DbContextOptions<TnADbContext>>());
case DbContextType.Payroll:
throw new ArgumentOutOfRangeException(nameof(key), key, null);
default:
throw new ArgumentOutOfRangeException(nameof(key), key, null);
}
});
并确保IDbContext不注入任何服务,而不是你可以尝试以下方法
private readonly IDbContext _context;
public InterfaceService(Func<DbContextType, IDbContext> resolver)
{
_context = resolver(DbContextType.TnA);
}
DbContext类型将是一个包含我需要注入的DB上下文类型的枚举。