将 Unity 中的不同数据库上下文映射到存储库接口的不同实例

本文关键字:存储 实例 接口 数据库 Unity 上下文 映射 | 更新日期: 2023-09-27 18:37:07

希望是关于使用Unity和Dependency Injection的快速问题。我已经在stackoverflow和搜索引擎上四处寻找,但还没有发现这是否可能。

我实际上有两个不同的数据库上下文,以及一个我想用于这两个上下文的通用存储库。

public static void RegisterComponents()
{
    var container = new UnityContainer();
    container.RegisterType<DbContext, DBContext1>(new PerResolveLifetimeManager());
    container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
    container.RegisterType<DbContext, DBContext2>(new PerResolveLifetimeManager());
    container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
    container.RegisterType<IUnitOfWork, UnitOfWork>();
    ......
    container.RegisterType<IGenderService, GenderService>();
    container.RegisterType<ILanguageService, LanguageService>();
    .......
     container.RegisterType<IPhotoService, PhotoService>();
}

但是,当我调用IPhotoService时,Visual Studio抛出一个错误,说模型(照片)不是上下文的一部分。这是因为照片模型位于 DBContext1 中,但代码后面使用 DBContext2 覆盖了 IRepository 映射。

有没有办法:

  • 命名这些不同的 DbContext 映射

  • 具有到不同数据库上下文的两个不同的 IRepository 映射

  • 将命名的 IRepository 映射注入到具体类中,例如 PhotoService?

谢谢

将 Unity 中的不同数据库上下文映射到存储库接口的不同实例

找到它,您可以在 Unity 中注册命名实例,如下所示:

container.RegisterType<Type2>("Instance 1", new ContainerControlledLifetimeManager());
container.RegisterType<Type2>("Instance 2", new ContainerControlledLifetimeManager());

然后解决它同样是:

Type2 instance1 = container.Resolve<Type2>("Instance 1");
 public static void RegisterComponents()
    {
        var container = new UnityContainer();
        container.RegisterType<DbContext, DBContext1>(new PerThreadLifetimeManager());
        container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
        container.RegisterType<IUnitOfWork, UnitOfWork>();
        container.RegisterType<IRepository<Photo>, Repository<Photo>>(new PerThreadLifetimeManager(),new InjectionConstructor(new DBContext2()));
        ....
        container.RegisterType<IGenderService, GenderService>();
        container.RegisterType<ILanguageService, LanguageService>();
        ....
        container.RegisterType<IPhotoService, PhotoService>();
        }

好的,我使用此代码解决了它,但不相信这是最好的方法。

基本上,IPhotoService使用需要DbContext2的IRepository。所以我在代码中编写了这个解析器,实际上将 DbContext 作为工作的注入构造函数传递。

DbContext1 上下文与 IGenderService、ILanguageService 一起工作,就像以前一样。

单独注册上下文。

container.RegisterType<DbContext, DBContext1>(new PerThreadLifetimeManager());
container.RegisterType<DbContext2, DbContext2>(new PerThreadLifetimeManager());

然后在存储库实例中,接受所有不同的 DbContext:

public class Repository<T>
{
    protected DbContext1 DbCtxt1 { get; }
    protected DbContext2 DbCtxt2 { get; }
    public Repository<T>(DbContext1 ctx1, DbContext2 ctx2)
    {
      DbCtxt1 = ctx1;
      DbCtxt2 = ctx2;
    }
}

然后,您可以指定一个作为默认值,但在通用存储库中构建一些逻辑,使您的类型 T 能够覆盖它。巨大的好处是您可以从保存服务访问所有不同的上下文。

也许它必须是一个接口,迫使子类实现 DbContext 选择器或其他东西,而不是纯粹的泛型 T。