我的容器中注册了几个组件,Windsor可以毫无问题地注入它们。 现在我以这种方式为NHibernate ISessionFactory添加了一个新注册:
foreach (KeyValuePair<string, string> _tenantItem in _contextWrapper.TenantsConnectionStrings)
{
var config = Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008
.UseOuterJoin()
.ConnectionString(_tenantItem.Value)
.FormatSql()
.ShowSql()
)
.ExposeConfiguration(ConfigurePersistence)
.ProxyFactoryFactory(typeof(ProxyFactoryFactory))
.BuildConfiguration();
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(config.BuildSessionFactory)
.Named(_tenantItem.Key)
.LifestyleTransient()
);
}
现在,如果我尝试检查我的容器,我会看到:
组件实现是“后期绑定”,Windsor不会注入它。
怎么了?我可以检查什么?
答案 0 :(得分:3)
这里有两个独立且无关的问题,让我依次回答。
“后期绑定”正如组件描述所说,仅仅意味着Windsor不会静态地知道ISessionFactory
的实现类型。这不是一个值得关注的理由。
在您的情况下,您只需指定工厂方法config.BuildSessionFactory()
即可构建实例,并且每次都可能不是同一类型。
可以实现工厂方法,如:
public ISessionFactory BuildSessionFactory()
{
if (Today == DayOfWeek.Friday)
{
return new BeerOClockSessionFactory();
}
return SomeOtherSessionFactory();
}
这很好而且很正常。
您提到的另一个问题是,您可能会遇到意外行为,其中ISessionFactory
的依赖性未达到预期效果。
可悲的是,除非你详细解释它,否则分享你所看到的那种错误我不认为除了说“它应该有效”之外我还能做些什么。
同样在我们参与其中的时候,我全心全意地同意@raulg的观点,认为会话工厂瞬态并不是一个特别好的主意。
答案 1 :(得分:2)
您可能不喜欢在运行时创建配置实例。
最好为配置创建一个合适的类,将其注册到容器中,然后使用它创建ISessionFactory实例。
public class MySessionFactoryBuilder : IMySessionFactoryBuilder
{
private FluentConfiguration _fluentConfiguration = null;
public MySessionFactoryBuilder()
{
}
void Initialize(string connectionStringKey)
{
IPersistenceConfigurer persistenceConfigurer = null;
persistenceConfigurer = MsSqlConfiguration.MsSql2008
.UseOuterJoin()
.ConnectionString(connectionStringKey)
.FormatSql()
.ShowSql()
;
_fluentConfiguration = Fluently.Configure()
.Database(persistenceConfigurer)
.ExposeConfiguration(ConfigurePersistence)
.ProxyFactoryFactory(typeof(ProxyFactoryFactory))
.BuildConfiguration()
;
}
public ISessionFactory BuildSessionFactory(string connectionStringKey)
{
Initialize(connectionStringKey);
return _fluentConfiguration.BuildSessionFactory();
}
}
您可以正常注册。然后在安装程序循环中注册多个ISessionFactory,每个租户一个:
foreach (KeyValuePair<string, string> _tenantItem in _contextWrapper.TenantsConnectionStrings)
{
container.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(k => k.Resolve<MySessionFactoryBuilder>().BuildSessionFactory(_tenantItem.Value))
.Named(_tenantItem.Key),
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.Named(_tenantItem.Key + "-nhsession")
.LifeStyle.Transient
);
}
注意,我注册了ISession瞬态,但没有注册ISessionFactory。通常,您希望尽可能长时间地保留ISessionFactory,因为创建它很昂贵。
我还没有对它进行过测试,但我猜它会解决它,因为会话工厂构建器的实现在编译时是已知的。