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