[英]Castle Windsor “Late bound” components
我的容器中已注册了多个组件,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不会注入它。
怎么了? 我可以检查什么?
这里有两个独立且无关的问题,因此让我依次回答。
组件描述中所说的“后期绑定”仅表示Windsor不静态地知道ISessionFactory
的实现类型。 这不是担心的原因。
这完全取决于您指定的工厂方法config.BuildSessionFactory()
在您的情况下为config.BuildSessionFactory()
来构建实例,并且每次都可能不是同一类型。
一个人可以实现如下的工厂方法:
public ISessionFactory BuildSessionFactory()
{
if (Today == DayOfWeek.Friday)
{
return new BeerOClockSessionFactory();
}
return SomeOtherSessionFactory();
}
这是正常的。
您提示的另一个问题表明您可能遇到了意外的行为,即对ISessionFactory
的依赖关系未按预期满足。
可悲的是,除非您对此有更多的解释,否则请分享您看到的那种错误,我认为除了说“它应该可以工作”之外,我没有什么可以帮助的。
同样,在我们讨论这个问题时,我完全同意@raulg的观点,即使会话工厂成为瞬态并不是一个特别好的主意。
可能不喜欢您在运行时创建配置实例。
您最好为配置创建一个合适的类,将其注册到容器中,然后使用该类来创建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保留得尽可能长,因为创建起来很昂贵。
我还没有测试它,但是我猜它会解决它,因为在编译时就知道会话工厂构建器的实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.