2012-05-14 2 views
1

У меня есть несколько компонентов, зарегистрированных в моем контейнере, и Windsor может вводить их без проблем. Теперь я добавил новую регистрацию для NHibernate ISessionFactory таким образом:Компоненты замка Windsor «Late bound»

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() 
        ); 
     } 

Теперь, если я стараюсь, чтобы проверить мой контейнер, я вижу:

enter image description here

Компонент реализация является «Late оценки» и Виндзор не будет вводить его.

Что случилось? Что я могу проверить?

ответ

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 как можно дольше, так как его очень сложно создать.

Я не тестировал его, но я предполагаю, что это разрешит его, поскольку реализация фабричного застройщика сеанса известна во время компиляции.

3

Здесь есть два отдельных и несвязанных вопроса, поэтому позвольте мне ответить на них по очереди.

«late bound» как указано в описании компонента, просто означает, что Windsor не знает тип реализации вашего ISessionFactory статически. Это не повод для беспокойства.

Это просто до заводского метода, который вы указываете, config.BuildSessionFactory() в вашем случае, чтобы создать экземпляр, и он может даже не быть одним и тем же типом каждый раз.

Можно реализовать фабричный метод, как:

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

Это хорошо и нормально.

Другой вопрос, на который вы намекали, указывает на то, что вы можете столкнуться с неожиданным поведением, когда зависимость от ISessionFactory не выполняется, как ожидалось.

К сожалению, если вы не объясните больше об этом, расскажите, какие ошибки вы видите. Я не думаю, что я могу помочь, кроме как сказать «он должен работать».

Кроме того, пока мы с этим согласны, я полностью согласен с @raulg, что создание переходного процесса на заводе не кажется особенно хорошей идеей.

+0

Может ли конфигурация (FluentConfiguration) фактически не зарегистрирована в контейнере? Вызов метода фабрики Fluently.Configure() будет похож на создание нового компонента, который не управляется контейнером? –

+0

нет.неважно, зарегистрировано ли оно. Я никогда не регистрирую его –

+0

@ KrzysztofKozmic не могли бы вы взглянуть на это: http://stackoverflow.com/questions/25064516/dependency-injection-lifestyle-service-shared-instance-between-2-instances-of? noredirect = 1 # comment39052582_25064516 –

Смежные вопросы