首页 > 解决方案 > 使用 Simple Injector 基于泛型类型将 DbContext 注入存储库

问题描述

考虑我有以下通用类:

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有两个构造函数。

考虑到我已经注入了ContextAand ,根据其通用参数值ContextB注入的最佳方法是什么?DbContextRepository

更新

我想注入DbContextRepository<T>,基于传递给初始化的类型Repository<T>

所以我可能有:

IRepository<Entity1> ...

Entity1可能在NameSpace.ContextA中。

标签: c#entity-framework.net-coresimple-injector

解决方案


您需要使用RegisterConditional接受 a 的重载Registration。这样,您可以将 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"));


推荐阅读