0

我有两个域,我通过两个应用程序接口访问它们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>();

然而,我的问题是我想IA2A1课堂上解决。理想情况下,我希望在父容器中拥有除会话工厂之外的所有内容。这只是存储库R1R2需要不同ISimpleSessionFactory的 s 但据我了解,如果未在子本地解决,它只会退回到父级,因此如果我将任何内容移至父级,它将找不到会话工厂。

4

2 回答 2

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 );
         }
     ) );
于 2013-07-15T12:42:57.633 回答
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>();

R1然后R2必须使用IASessionFactoryand IBSessionFactory,而不是ISimpleSessionFactory

于 2013-07-15T09:11:02.407 回答