Unity не использует конструктор класса по умолчанию - PullRequest
18 голосов
/ 10 марта 2011

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

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 ]

55 голосов
/ 10 марта 2011

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 вызовет исключение.

21 голосов
/ 10 марта 2011

Просто попробуйте зарегистрировать тип так:

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

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

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

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