将 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 中注册命名实例,如下所示:
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。