Как Unity.Resolve узнает, какой конструктор использовать? - PullRequest
35 голосов
/ 18 марта 2010

Учитывая класс с несколькими конструкторами - как я могу сказать 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, как Resolve узнает, какой конструктор использовать? И как я могу сказать, чтобы использовать правильный? Допустим, у меня есть контейнер с зарегистрированным IBar - поймет ли он, что он должен отдавать предпочтение конструктору, принимающему IBar? И если я тоже укажу строку - будет ли она использовать конструктор (string, IBar)?

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

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

Ответы [ 2 ]

59 голосов
/ 18 марта 2010

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

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

33 голосов
/ 18 марта 2010

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

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

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

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

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

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

Гораздо безопаснее написать свой код дружественным к DI, но независимым от контейнера способом .

...