1

我的容器中注册了几个组件,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 不会注入它。

怎么了?我可以检查什么?

4

2 回答 2

3

这里有两个独立且不相关的问题,所以让我依次回答。

正如组件描述所说, “后期绑定”仅仅意味着温莎不知道你的ISessionFactory静态实现类型。这不是担心的理由。

在您的情况下,构建实例完全取决于您指定的工厂方法,config.BuildSessionFactory()而且它甚至可能每次都不是相同的类型。

可以实现工厂方法,例如:

public ISessionFactory BuildSessionFactory()
{
   if (Today == DayOfWeek.Friday)
   {
      return new BeerOClockSessionFactory();
   }
   return SomeOtherSessionFactory();
}

这很好,很正常。

您暗示的另一个问题表明您可能会遇到意外行为,其中对 的依赖ISessionFactory未按预期满足。

可悲的是,除非您对此进行更多解释,否则请分享您所看到的错误类型,我认为除了说“它应该可以正常工作”之外,我无能为力。

同样,当我们这样做时,我完全同意@raulg 的观点,即使会话工厂瞬态听起来不是一个特别好的主意。

于 2012-05-14T21:27:41.747 回答
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,因为创建它的成本很高。

我还没有测试过它,但我猜这会解决它,因为会话工厂构建器的实现在编译时是已知的。

于 2012-05-14T17:26:16.543 回答