如何在Unity中配置多个连接工厂?

时间:2013-07-15 08:50:34

标签: c# unity-container

我有两个域,我通过两个应用程序接口IA1IA2访问它们,它们各自使用不同的存储库R1R2。存储库使用一个接口,让他们创建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>();

我的问题是,我想要从IA2课程解决A1。理想情况下,我想在父容器中拥有除会话工厂之外的所有内容。只是存储库R1R2需要不同的ISimpleSessionFactory,但据我了解它只会在子节点本地解析时才会回到父节点,所以如果我移动任何内容父母不会找到会议工厂。

2 个答案:

答案 0 :(得分:2)

如果我理解你的问题,我相信你可以使用命名注册而不需要两个独立的接口:

  // 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

这里的诀窍是以某种方式注册IA1R1(和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 );
         }
     ) );

答案 1 :(得分:0)

直到我听到更好的答案,我这样做,为两个会话工厂定义单独的接口,以便它们都可以在同一个容器中注册。

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>();

R1R2必须使用IASessionFactoryIBSessionFactory,而不是ISimpleSessionFactory