如何在Unity中配置多个连接工厂
本文关键字:连接 工厂 配置 Unity | 更新日期: 2023-09-27 18:22:33
我有两个域,通过两个应用程序接口IA1
、IA2
访问,它们分别使用不同的存储库R1
和R2
。存储库使用一个接口来创建NHibernate会话ISimpleSessionFactory
。
如果存储库共享一个数据库,我会使用统一容器将它们设置为这样:
var unity = new UnityContainer();
unity.RegisterType<ISimpleSessionFactory, NHibernateSessionFactory>(
new ContainerControlledLifetimeManager(), new InjectionConstructor("ConnectionA"));
unity.RegisterType<IA1, A1>();
unity.RegisterType<R1>();
unity.RegisterType<IA2, A2>();
unity.RegisterType<R2>();
但它们不共享连接字符串,所以我想做这样的事情:
var unity = new UnityContainer();
var child1 = unity.CreateChildContainer();
child1.RegisterType<ISimpleSessionFactory, NHibernateSessionFactory>(
new ContainerControlledLifetimeManager(), new InjectionConstructor("ConnectionA"));
child1.RegisterType<IA1, A1>();
child1.RegisterType<R1>();
var child2 = unity.CreateChildContainer();
child2.RegisterType<ISimpleSessionFactory, NHibernateSessionFactory>(
new ContainerControlledLifetimeManager(), new InjectionConstructor("ConnectionB"));
child2.RegisterType<IA2, A2>();
child2.RegisterType<R2>();
然而,我的问题是,我想从A1
类中解决IA2
。理想情况下,我希望除了会话工厂之外的所有东西都在父容器中。只是存储库R1
和R2
需要不同的ISimpleSessionFactory
,但据我所知,如果不在child中本地解析,它只会回到parent,所以如果我将任何内容移动到parent,它就找不到会话工厂。
如果我正确理解您的问题,我相信您可以使用命名注册,而不需要两个单独的接口:
// first named registration
child1.RegisterType<ISimpleSessionFactory, NHibernateSessionFactory>(
new ContainerControlledLifetimeManager(),
new InjectionConstructor("ConnectionA"), "ConnectionA");
child1.RegisterType<IA1, A1>( new InjectionConstructor( new ResolvedParameter<ISimpleSessionFactory>("ConnectionA"));
child1.RegisterType<R1>( new InjectionConstructor( new ResolvedParameter<ISimpleSessionFactory>("ConnectionA") );
// the same goes for the second one, just create a named registration
// under a different name
这里的技巧是注册IA1
和R1
(分别为IA2
/R2
),以便您精确地指出应该如何解析参数(ResolvedParameter
指向命名注册)。
请注意,如果服务的构造函数具有更多参数,则InjectionConstructor
不可用。在这种情况下,使用InjectionFactories
代替
child1.RegisterType<IA1, A1>(
new InjectionFactory( container =>
{
// arbitrarily complicated imperative code to create an instance
// first resolve ISimpleSessionFactory by name
ISimpleSessionFactory factory =
container.Resolve<ISimpleSessionFactory>( "ContainerA" );
// then create A1
return new A1( factory, any, other, parameters, here );
}
) );
在得到更好的答案之前,我一直在做这件事,为两个会话工厂定义单独的接口,以便它们都可以在同一个容器中注册。
interface IASessionFactory : ISimpleSessionFactory{}
interface IBSessionFactory : ISimpleSessionFactory{}
class ASessionFactory : NHibernateSessionFactory, IASessionFactory{...}
class BSessionFactory : NHibernateSessionFactory, IBSessionFactory{...}
var unity = new UnityContainer();
unity.RegisterType<IASessionFactory, ASessionFactory>(
new ContainerControlledLifetimeManager(), new InjectionConstructor("ConnectionA"));
unity.RegisterType<IBSessionFactory, BSessionFactory>(
new ContainerControlledLifetimeManager(), new InjectionConstructor("ConnectionB"));
unity.RegisterType<IA1, A1>();
unity.RegisterType<R1>();
unity.RegisterType<IA2, A2>();
unity.RegisterType<R2>();
R1
和R2
必须使用IASessionFactory
和IBSessionFactory
,而不是ISimpleSessionFactory
。