使用 Simple Injector 根据通用类型将 DbContext 注入存储库
Inject DbContext to repository based on the generic type using Simple Injector
考虑我有以下通用 class:
public class Repository<T> : IRepository<T> where T : class
{
private DbContext Context { get; set; }
public Repository(DbContext context)
{
Context = context;
}
}
然后我使用 SimpleInjector 如下注册了两个不同的 dbcontext:
container.Register<ContextA>(
()=> new ContextA(SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options));
container.Register<ContextB>(
() => new ContextB(SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options));
然后我对 dbContext 进行了以下注册:
container.RegisterConditional(
typeof(DbContext),
typeof(ContextA),
c=> c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextA"));
container.RegisterConditional(
typeof(DbContext),
typeof(ContextB),
c => c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextB"));
当代码到达 container.RegisterConditional 时它抛出错误并抱怨 ContextA
有两个构造函数。
考虑到我已经注入了 ContextA
和 ContextB
,根据通用参数值为 Repository
注入合适的 DbContext
的最佳方法是什么?
更新
我想注入 DbContext
到 Repository<T>
,基于传递给初始化 Repository<T>
的类型。
所以我可能有:
IRepository<Entity1> ...
Entity1
可能在 NameSpace.ContextA.
您需要使用接受 Registration
的 RegisterConditional
重载。这样您就可以将 lambda 表达式包装在 Registration
中,如下所示:
var contextARegistration =
Lifestyle.Scoped.CreateRegistration(
() => new ContextA(
SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options),
container);
container.RegisterConditional(
typeof(DbContext),
contextARegistration,
c => c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextA"));
var contextBRegistration =
Lifestyle.Scoped.CreateRegistration(
() => new ContextB(
SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options),
container);
container.RegisterConditional(
typeof(DbContext),
contextBRegistration,
c => c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextB"));
考虑我有以下通用 class:
public class Repository<T> : IRepository<T> where T : class
{
private DbContext Context { get; set; }
public Repository(DbContext context)
{
Context = context;
}
}
然后我使用 SimpleInjector 如下注册了两个不同的 dbcontext:
container.Register<ContextA>(
()=> new ContextA(SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options));
container.Register<ContextB>(
() => new ContextB(SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options));
然后我对 dbContext 进行了以下注册:
container.RegisterConditional(
typeof(DbContext),
typeof(ContextA),
c=> c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextA"));
container.RegisterConditional(
typeof(DbContext),
typeof(ContextB),
c => c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextB"));
当代码到达 container.RegisterConditional 时它抛出错误并抱怨 ContextA
有两个构造函数。
考虑到我已经注入了 ContextA
和 ContextB
,根据通用参数值为 Repository
注入合适的 DbContext
的最佳方法是什么?
更新
我想注入 DbContext
到 Repository<T>
,基于传递给初始化 Repository<T>
的类型。
所以我可能有:
IRepository<Entity1> ...
Entity1
可能在 NameSpace.ContextA.
您需要使用接受 Registration
的 RegisterConditional
重载。这样您就可以将 lambda 表达式包装在 Registration
中,如下所示:
var contextARegistration =
Lifestyle.Scoped.CreateRegistration(
() => new ContextA(
SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options),
container);
container.RegisterConditional(
typeof(DbContext),
contextARegistration,
c => c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextA"));
var contextBRegistration =
Lifestyle.Scoped.CreateRegistration(
() => new ContextB(
SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(), sqlConnection).Options),
container);
container.RegisterConditional(
typeof(DbContext),
contextBRegistration,
c => c.Consumer.ImplementationType.GenericTypeArguments
.Any(r => r.Namespace == "NameSpace.ContextB"));