2017-01-06 5 views
0

У меня недавно возник вопрос от коллеги о том, как работает инъекция зависимостей. В следующей статье объясняется это четко.Как работает инъекция зависимостей конструктора?

https://blogs.endjin.com/2014/04/understanding-dependency-injection/

Однако, у меня есть конкретный вопрос, который я до сих пор не могу ответить, потому что я не понимаю: Как конструктор, не вызывается с помощью использования методов, как .Resolve или .GetInstance получить создан? Является ли инфраструктура DI каким-то образом перехватывать их и предоставлять требуемые зависимости конструктора?

+0

Ваш вопрос непонятен. Вы имели в виду «Как вызвать вызов конструктора с использованием таких методов, как .Resolve или .GetInstance? – Spock

ответ

1

Он обычно использует отражение, чтобы исследовать подпись конструктора и передать соответствующие параметры. Фактическое создание может быть выполнено с использованием Activator.CreateInstance (см. https://msdn.microsoft.com/en-us/library/wcxyzt4d(v=vs.110).aspx).

1

Прежде всего важно понимать, что DI doet not требует использования библиотеки DI a.k.a. DI Container. DI - это набор принципов и практик, и DI Container является дополнительным инструментом. Применение DI без a Контейнер - это практика, называемая Pure DI. This article, this и this описывают, когда вы должны использовать контейнер.

Это говорит о том, что инжектор конструктора - это всего лишь акт , статически объявляющий требуемые зависимости класса как аргументы конструктора. Без использования контейнера это означает, что «кто-то» все равно вызовет такой конструктор явно (используя простой старый код) и передаст его зависимости.

Тем не менее, мы стараемся не допустить «нормальных» частей приложения от вызова этих конструкторов, потому что это снова приведет к тесно связанному коду. Вместо этого мы переместим эту конструкцию в точку входа приложения, так называемый Composition Root.

Такая конструкция в точке входа может выглядеть следующим образом:

public Controller CreateController(Type type) 
{ 
    if (type == typeof(HomeController)) 
     return new HomeController(
      new UserServices(
       new LoggingUsersRepositoryDecorator(
        new FileLogger(), 
        new UsersRepository(connectionString)))); 

    if (type == ...) 

    return base.CreateController(type); 
} 

Если бы мы должны были использовать DI контейнер, мы бы только указать сопоставления между абстракциями и реализациями в контейнере; нам не нужно указывать зависимости, требуемые классом. Тем не менее, остается то же самое место, где мы «прокладываем» и «решаем». Как при использовании Pure DI, так и при использовании инструмента мы делаем это в корне композиции .

Смежные вопросы