Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 在Windsor容器中为同一类型注册多个实例的正确方法是什么?_.net_Castle Windsor_Ioc Container - Fatal编程技术网

.net 在Windsor容器中为同一类型注册多个实例的正确方法是什么?

.net 在Windsor容器中为同一类型注册多个实例的正确方法是什么?,.net,castle-windsor,ioc-container,.net,Castle Windsor,Ioc Container,我正在将CommonServiceLocator与WindworContainer一起用于解析我的NHibernage.ISession实例。ISession实例是通过SessionFactory创建的。出于某种原因,我需要在一个应用程序中使用不同的数据库,因此我需要不同的连接字符串和不同的NHibernate.ISession对象 SessionFactory可以按DB名称创建不同的ISession对象。因此,我希望使用以下语法在应用程序中获取不同的ISession对象: ISesssion

我正在将CommonServiceLocator与WindworContainer一起用于解析我的NHibernage.ISession实例。ISession实例是通过SessionFactory创建的。出于某种原因,我需要在一个应用程序中使用不同的数据库,因此我需要不同的连接字符串和不同的NHibernate.ISession对象

SessionFactory可以按DB名称创建不同的ISession对象。因此,我希望使用以下语法在应用程序中获取不同的ISession对象:

ISesssion sessionForDb1 = ServiceLocator.Current.GetInstance<ISession>("session-for-db1");
ISesssion sessionForDb2 = ServiceLocator.Current.GetInstance<ISession>("session-for-db2");
isession sessionForDb1=ServiceLocator.Current.GetInstance(“session-for-db1”);
isession sessionForDb2=ServiceLocator.Current.GetInstance(“session-for-db2”);
为了实现这一点,我创建了以下容器注册:

IWindsorContainer container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();

container.Register(
    Component.For<ISessionFactory>()
        .Named("session-factory-for-db1")
        .LifeStyle.Singleton
        .UsingFactoryMethod(() => new NHibernateConfigurator().CreateSessionFactoryForDb1()),

    Component.For<ISessionFactory>()
        .Named("session-factory2-for-db2")
        .LifeStyle.Singleton
        .UsingFactoryMethod(() => new NHibernateConfigurator().CreateSessionFactoryForDb2()),

    Component.For<ISession>()
        .Named("session-for-db1")
        .LifeStyle.PerWebRequest
        .UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>("session-factory-for-db1").OpenSession()),

    Component.For<ISession>()
        .Named("session-for-db2")
        .LifeStyle.PerWebRequest
        .UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>("session-factory2-for-db2").OpenSession())
        );

 ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
IWindsorContainer=new WindsorContainer();
container.AddFacility();
集装箱。登记(
用于()的组件
.命名为(“session-factory-for-db1”)
.单身汉
.UsingFactoryMethod(()=>新的NHibernateConfigulator().CreateSessionFactoryForDb1()),
用于()的组件
.Named(“session-factory2-for-db2”)
.单身汉
.UsingFactoryMethod(()=>新的NHibernateConfigulator().CreateSessionFactoryForDb2()),
用于()的组件
.Named(“session-for-db1”)
.livelope.PerWebRequest
.UsingFactoryMethod(kernel=>kernel.Resolve(“session-factory-for-db1”).OpenSession(),
用于()的组件
.Named(“session-for-db2”)
.livelope.PerWebRequest
.UsingFactoryMethod(kernel=>kernel.Resolve(“session-factory2-for-db2”).OpenSession()
);
ServiceLocator.SetLocatorProvider(()=>新WindsorServiceLocator(容器));
这是可行的,但我不喜欢这里的东西是,我需要创建许多表示对象族的字符串常量,并使用命名每个实例的其他字符串来构建它们。因此,对于这个任务,我需要注册4个字符串常量,如果我的SessionFactory必须用另一个工厂创建,我可能需要定义6个常量,等等


我想知道是否有更好的方法来注册类似的对象族?

当有多个服务具有相同的服务类型时,您必须使用组件id(字符串)来区分它们。在您的情况下,如果您从未将任何ISessionFactory直接注入到类中,则可以将此注册包装在扩展方法中,例如:

public static class WindsorSessionFactoryExtensions {
    public static void RegisterSession(this IWindsorContainer container, string name, Func<NHibernateConfigurator, ISessionFactory> configurator) {
        var id = Guid.NewGuid().ToString();
        container.Register(
            Component.For<ISessionFactory>()
                .Named(id)
                .LifeStyle.Singleton
                .UsingFactoryMethod(() => configurator(new NHibernateConfigurator())),
            Component.For<ISession>()
                .Named(name)
                .LifeStyle.PerWebRequest
                .UsingFactoryMethod(k => k.Resolve<ISessionFactory>(id).OpenSession())
            );
    }
}

container.RegisterSession("session-for-db1", c => c.CreateSessionFactoryForDb1());
container.RegisterSession("session-for-db2", c => c.CreateSessionFactoryForDb2());
var session = container.Resolve<ISession>("session-for-db1");
公共静态类WindsorSessionFactoryExtensions{
公共静态无效注册表会话(此IWindsorContainer容器、字符串名称、函数配置器){
var id=Guid.NewGuid().ToString();
集装箱。登记(
用于()的组件
.姓名(id)
.单身汉
.UsingFactoryMethod(()=>configurator(新的NHibernateConfigulator()),
用于()的组件
.姓名(姓名)
.livelope.PerWebRequest
.UsingFactoryMethod(k=>k.Resolve(id).OpenSession())
);
}
}
RegisterSession(“session-for-db1”,c=>c.CreateSessionFactoryForDb1());
RegisterSession(“session-for-db2”,c=>c.CreateSessionFactoryForDb2());
var session=container.Resolve(“session-for-db1”);
或者,您可以做一些类似于
var id=name+“-factory”
之类的事情,比如约定,而不是为会话工厂id使用GUID

另一种可能是使用ExtendedProperties,但这可能会使事情变得更加复杂,最终总会出现某种类型的鉴别器


但这里真正的问题是您正在使用服务定位器。在正常的容器使用中,您不应该使用它。相反,请使用服务覆盖来定义所注册组件中需要的会话。

当有多个服务具有相同的服务类型时,您必须使用组件id(字符串)来区分它们。在您的情况下,如果您从未将任何ISessionFactory直接注入到类中,则可以将此注册包装在扩展方法中,例如:

public static class WindsorSessionFactoryExtensions {
    public static void RegisterSession(this IWindsorContainer container, string name, Func<NHibernateConfigurator, ISessionFactory> configurator) {
        var id = Guid.NewGuid().ToString();
        container.Register(
            Component.For<ISessionFactory>()
                .Named(id)
                .LifeStyle.Singleton
                .UsingFactoryMethod(() => configurator(new NHibernateConfigurator())),
            Component.For<ISession>()
                .Named(name)
                .LifeStyle.PerWebRequest
                .UsingFactoryMethod(k => k.Resolve<ISessionFactory>(id).OpenSession())
            );
    }
}

container.RegisterSession("session-for-db1", c => c.CreateSessionFactoryForDb1());
container.RegisterSession("session-for-db2", c => c.CreateSessionFactoryForDb2());
var session = container.Resolve<ISession>("session-for-db1");
公共静态类WindsorSessionFactoryExtensions{
公共静态无效注册表会话(此IWindsorContainer容器、字符串名称、函数配置器){
var id=Guid.NewGuid().ToString();
集装箱。登记(
用于()的组件
.姓名(id)
.单身汉
.UsingFactoryMethod(()=>configurator(新的NHibernateConfigulator()),
用于()的组件
.姓名(姓名)
.livelope.PerWebRequest
.UsingFactoryMethod(k=>k.Resolve(id).OpenSession())
);
}
}
RegisterSession(“session-for-db1”,c=>c.CreateSessionFactoryForDb1());
RegisterSession(“session-for-db2”,c=>c.CreateSessionFactoryForDb2());
var session=container.Resolve(“session-for-db1”);
或者,您可以做一些类似于
var id=name+“-factory”
之类的事情,比如约定,而不是为会话工厂id使用GUID

另一种可能是使用ExtendedProperties,但这可能会使事情变得更加复杂,最终总会出现某种类型的鉴别器


但这里真正的问题是您正在使用服务定位器。在正常的容器使用中,您不应该使用它。相反,请使用服务覆盖来定义您希望在注册组件中使用的会话。

非常感谢,您能否用多一点的话描述一下您对服务定位器的看法。为什么我不用用它?服务覆盖在这种情况下是如何应用的呢?服务定位器,请参阅服务覆盖:非常感谢,您能否用多一点的话描述一下您对服务定位器的看法。为什么我不用用它?在这种情况下,服务覆盖是如何应用的?有关服务定位器,请参阅re se