Подтвердить что ты не робот

Как Unity.Resolve знает, какой конструктор использовать?

Учитывая класс с несколькими конструкторами - как я могу сказать, разрешить какой конструктор использовать?

Рассмотрим следующий пример класса:

public class Foo
{
    public Foo() { }
    public Foo(IBar bar)
    {
        Bar = bar;
    }
    public Foo(string name, IBar bar)
    {
        Bar = bar;
        Name = name;
    }
    public IBar Bar { get; set; }        
    public string Name { get; set; }
}

Если я хочу создать объект типа Foo, используя Resolve, как будет решить, какой конструктор использовать? И как я могу сказать, чтобы использовать правильный? Скажем, у меня есть контейнер с зарегистрированным IBar - поймет ли он, что он должен одобрить конструктор, принимающий IBar? И если я также укажу строку - будет ли она использовать конструктор (string, IBar)?

Foo foo = unityContainer.Resolve<Foo>(); 

И, пожалуйста, проигнорируйте тот факт, что, вероятно, было бы проще, если бы у класса был только один конструктор...

4b9b3361

Ответ 1

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

Взято из текст ссылки

Ответ 2

Когда вы регистрируете тип, вы можете указать, какой конструктор использовать следующим образом:

container.RegisterType<Foo>(
    new InjectionConstructor(
        new ResolvedParameter<IBar>()));

Вышеприведенный код из памяти, но общий принцип. В этом случае я выбрал конструктор, который принимает единственный параметр типа IBar.

И, пожалуйста, проигнорируйте тот факт, что, вероятно, было бы проще, если бы у класса был только один конструктор...

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

Конечно, Unity, скорее всего, выяснит это для вас, но тогда вы будете полагаться на конкретное поведение контейнера вместо правильного проектирования вашего API. Другие контейнеры могут иметь другое поведение, поэтому, если вы когда-либо захотите перенести из Unity в лучший контейнер, могут возникнуть тонкие ошибки.

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