Unity не использует конструктор класса по умолчанию

У меня есть этот класс:

public class Repo
{
   public Repo() : this(ConfigurationManager.AppSettings["identity"],       ConfigurationManager.AppSettings["password"])

    {

    }

   public Repo(string identity,string password)
   {
       //Initialize properties.
   }

}

Я добавил строку в web.config, чтобы этот тип автоматически создавался контейнером Unity.

но во время выполнения моего приложения я получаю это сообщение об ошибке:

  "System.InvalidOperationException : the parameter identity could not be resolved when attempting to call constructor Repo(String identity, String password)  -->Microsoft.Practices.ObjectBuilder2.BuildFailedException : The current Build operation ...."

1) Почему Unity не использует конструктор по умолчанию?

2) Предположим, я хочу, чтобы Unity использовал второй конструктор (параметризованный). Как передать эту информацию в Unity через файл конфигурации?

2 ответа

Решение

Unity по умолчанию выбирает конструктор с наибольшим количеством параметров. Вы должны указать Unity, чтобы он явно использовал другой.

Один из способов сделать это - использовать атрибут [InjectionConstructor], например:

using Microsoft.Practices.Unity;

public class Repo
{
   [InjectionConstructor]
   public Repo() : this(ConfigurationManager.AppSettings["identity"], ConfigurationManager.AppSettings["password"])
   {

   }

   public Repo(string identity,string password)
   {
       //Initialize properties.
   }
}

Второй способ сделать это, если вы не хотите загромождать классы / методы атрибутами, - это указать, какой конструктор использовать при настройке контейнера с помощью InjectionConstructor:

IUnityContainer container = new UnityContainer();
container.RegisterType<Repo>(new InjectionConstructor());

Из документации:

Как Unity разрешает целевые конструкторы и параметры

Когда целевой класс содержит более одного конструктора, Unity будет использовать тот, к которому применен атрибут InjectionConstructor. Если имеется более одного конструктора и ни один из них не содержит атрибута InjectionConstructor, Unity будет использовать конструктор с наибольшим количеством параметров. Если имеется более одного такого конструктора (более одного из "самых длинных" с одинаковым количеством параметров), Unity вызовет исключение.

Просто попробуйте зарегистрировать тип следующим образом:

<register type="IRepo" mapTo="Repo">
  <constructor />
</register>

Из-за нет param элемент, указанный в constructor элемент должен вызывать конструктор по умолчанию.

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

container.RegisterType<IRepo, Repo>(new InjectionConstructor());

У меня была более простая проблема, которая привела к этой ошибке.

Контейнер, который я использовал был неправильный контейнер. Я случайно создал два разных контейнера, и мой контейнер.RegisterType находился внутри другого контейнера, чем тот, который использовался.

Другие вопросы по тегам