Внедрение Ctor в контейнер C # Unity

#c# #mapping #unity-container #containers

#c# #сопоставление #unity-контейнер #контейнеры

Вопрос:

Допустим, у нас есть:

 class A
{
   ILogger myLog;
   A(ILogger log)
   {
      this.myLog = log;
   }
 ...
}
  

И мы уже зарегистрировали интерфейс ILogger ранее в контейнере Unity, например

  container.RegisterType<ILogger, SomeLogger>();
  

И здесь класс SomeLogger:

 class SomeLogger : ILogger
{
   string myString;
   SomeLogger(string test)
   {
     myString = test;
   }
 ...
}
  

Теперь, как unity может создать экземпляр SomeLogger для класса A, не передавая строку ctor SomeLogger?
Предположим, что для SomeLogger нет другого ctor. Где можно указать параметры для ctor сопоставленного типа SomeLogger?

Ответ №1:

Вы можете сделать это в своей конфигурации:

 <?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
    </configSections>
    <unity>
        <containers>
            <container>
                <types>
                    <type type="[Namespace].ILogger, [AssemblyName]" mapTo="[Namespace].SomeLogger, [AssemblyName]">
                        <constructor>
                            <param name="test">
                                <value value="MyDesiredValue" />
                            </param>
                        </constructor>
                    </type>
                </types>
            </container>
        </containers>
  </unity>
</configuration>
  

Это также декларативно регистрирует ваш тип, поэтому

 container.RegisterType<ILogger, SomeLogger>();
  

вызов больше не требуется.

-Doug

Комментарии:

1. Спасибо за этот пример. Как можно указать это в коде? В удвоении говорится только о параметрах ctor для типа внедрения, но не для отображаемого типа интерфейса.

Ответ №2:

Вы можете сделать это:

 container.RegisterType<ILogger, SomeLogger>(new InjectionConstructor("myStringValue"));
  

Ответ №3:

вы также можете сделать это в регистрационном коде следующим образом:

 UnityContainer.RegisterType<ILogger, SomeLogger>();
UnityContainer.Configure<InjectedMembers>()
              .ConfigureInjectionFor<SomeLogger>(new InjectionConstructor("TestString"));
  

Комментарии:

1. Большое спасибо, это именно то, что я искал. В моей конкретной проблеме у меня есть класс обратного вызова WFC, и ctor-клиент WCF нуждается в контексте экземпляра. До сих пор я не знал, как передать контекст этого экземпляра в контейнер unity для сопоставления для клиента WCF.

2. Существует перегрузка для RegisterType, которая принимает параметр InjectionMember[], который вы можете использовать для прямой передачи InjectionConstrutor . Нет необходимости вызывать configure отдельно.

3. Что произойдет, если не предоставить строковый параметр для контейнера unity? Исключение времени выполнения?

4. @Juergen Я не знаю, я бы предположил null , что передается для типов с нулевым значением? Мне нужно будет это проверить..