2015-07-08 3 views
3

Я знаю, что на впрыскивании зависимостей много нитей и нитей, но не так много на Depenedency-Injection-Containers. Я нашел this one by Fabien Potencier весьма полезным, хотя он нацелен на PHP. Однако чем больше я читаю об этих контейнерах, я прихожу к выводу, что это не что иное, как простая коллекция заводских методов, это правда?DI-контейнер против заводов

Более глубокое и более конкретный вид: При внутривенном введении зависимость к объекту

foo.Bar = new Dependency(); 

Я мог бы также написать

foo.Bar = new myFactory.CreateDependency(); 

или с контейнером

foo.Bar = myContainer.CreateDependency(); 

Здесь контейнер в рамках последнего подхода не содержит только один, но многие другие методы для создания другие типы также, так что это просто контейнер для заводских методов, не так ли?

ответ

2

Весь смысл контейнеров DI является то, что вам не нужно/должны написать код, как

foo.Bar = myContainer.CreateDependency(); 

Это считается антипаттерн. Контейнер DI следует использовать только один раз в корне композиции (это основной шаблон использования контейнера DI).

Контейнер DI автоматически создает объекты и устанавливает зависимости через конструкторы или свойства на основе конфигурации. В случае Factory вы должны делать все сами. Помимо создания контейнеров DI, вы предоставляете:

Управление LifeTime. Таким образом, каждый раз, когда требуется зависимость, контейнер может вводить один и тот же объект (однопользовательское время жизни) или возвращать каждый раз каждый раз.

Ограниченные возможности АОП, такие как перехват вызова метода и выполнение пользовательской логики до и после методов.

Вы можете ознакомиться с этой книгой Dependency Injection in .NET. Это помогло мне понять контейнеры DI, образцы использования и инъекции зависимостей в целом.

+0

Но как узнать, как WHEN построить новый экземпляр любого класса? – HimBromBeere

+0

Конечно, должен быть явный вызов контейнера DI, и это должно быть сделано в некоторой «точке входа». Например, в веб-приложении этот момент представляет собой создание контроллера, где вызывается решение: container.Resolve . Но SomeController сам не знает, что используется контейнер DI. В этом суть структуры корневого состава. – wunzsh

1

DI-Container можно рассматривать как большой набор умных фабричных методов, который настраивается несколькими способами (код, xml, авто-отображение). Я назвал эти заводские методы интеллектуальными, потому что контейнер отслеживает зарегистрированные типы и использует их для создания более сложных объектов. При использовании заводов вам необходимо самостоятельно установить эти зависимости, иначе вы уже используете контейнер-зависимость.

0

В идеале код не должен знать, что он работает с DI. Он просто экстернализирует свои зависимости и предполагает, что они предоставляются.

0

Вы можете увидеть DI-контейнер/библиотеку как фабричную структуру с множеством методов построения объектов высокого уровня (через отражение). Это полезно, потому что обычно вам не нужно писать какой-либо высокоуровневый метод, например, для загрузки сборников плагинов и получения типов данных плагина. Но недостатком является то, что отражение происходит медленно, и разумно использовать его во время фазы инициализации приложения. Но если вы хотите создать с ним много мелких объектов во время выполнения, это замедлит вас.

С другой стороны, ваши собственные заводы изготовлены на заказ и обычно содержат список конкретных реализаций и большой коммутационный шкаф, карту или что-то в этом роде. Они работают быстрее, но вам нужно написать всю логику построения объекта самостоятельно.

Вам не нужно выбирать между этими двумя вариантами, которые вы можете комбинировать. Например, вы можете построить сложные заводы через DI

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