Укажите конструктор для контейнера Unity IoC для использования
Я использую контейнер Unity IoC для разрешения своих объектов. Однако я столкнулся с проблемой. Когда у меня есть несколько конструкторов - как Unity знает, какой из них использовать? Кажется, он использует один с параметрами, когда у меня есть один и один без. Можно ли явно указать, какой конструктор использовать?
В частности, у меня был случай, похожий на следующий класс Person с двумя конструкторами. В этом случае я хочу, чтобы контейнер IoC использовал конструктор по умолчанию - без параметров - но он выбирает параметр с параметрами.
public class SomeValueObject
{
public SomeValueObject(string name)
{
Name = name;
}
public string Name { get; set; }
}
public class Person
{
private string _name;
public Person()
{
_name = string.Empty;
}
public Person(SomeValueObject obj)
{
_name = obj.Name;
}
}
Это явно не удается, поскольку он не может создать SomeValueObject - не зная, что нужно вводить в свой строковый параметр. Ошибка, которую он дает:
Сбой разрешения зависимостей, type = "MyApp.Person", name = "". Сообщение об исключении: текущая операция сборки (ключ сборки Build Key [MyApp.Person, null]) не удалось: параметр obj не удалось устранить при попытке вызвать конструктор MyApp.Person(MyApp.SomeValueObject obj). (Тип стратегии BuildPlanStrategy, индекс 3)
Регистрация контейнера:
Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());
И разрешение:
var person = Container.Resolve<Person>();
Ответы
Ответ 1
Зарегистрируйте его следующим образом:
container.RegisterType<Person>(new InjectionConstructor());
Вы также можете добавить LifetimeManager, используя перегрузку метода RegisterType.
Тем не менее, при моделировании для DI ваша жизнь будет намного проще, если у вас есть однозначные конструкторы (т.е. перегруженные конструкторы).
Ответ 2
По умолчанию Unity выбирает конструктор с максимальным количеством аргументов. Чтобы переопределить это, украсьте требуемый конструктор InjectionConstructorAttribute.
Ответ 3
Инъекция с несколькими конструкторами с использованием атрибута
Когда целевой класс содержит больше, чем один конструктор с таким же числом параметров, вы должны применить Атрибут InjectionConstructor. конструктор, который контейнер Unity будет использовать, чтобы указать, какой конструктор контейнер должен использовать. Как и в случае автоматическая инъекция конструктора, вы может указывать параметры конструктора как конкретный тип, или вы можете указать интерфейс или базовый класс, для которого контейнер Unity содержит зарегистрированное отображение.
Ответ 4
Мне действительно нужно указать, как вы используете инъекцию зависимостей в этом случае, это просто неправильно. Контейнер должен иметь возможность встраивать SomeValueObject в конструкцию.
Скорее всего, вам нужно зарегистрировать объект SomeValueObject по умолчанию, который возвращает свойство .Name string.Empty
.