2010-01-03 4 views
46

Я решил использовать принципы IoC в более крупном проекте. Тем не менее, я хотел бы получить что-то прямое, что беспокоило меня в течение длительного времени. Вывод, который я придумал, заключается в том, что контейнер IoC является архитектурным шаблоном, а не шаблоном проектирования. Другими словами, ни один класс не должен знать о его присутствии, и сам контейнер должен использоваться на уровне приложения, чтобы сшить все компоненты. По существу, он становится опцией, на вершине хорошо продуманной объектно-ориентированной модели. Сказав это, как можно получить доступ к разрешенным типам без разбрызгивания контейнеров IoC по всему месту (независимо от того, они абстрагированы или нет)? Единственный вариант, который я вижу здесь, - использовать абстрактные фабрики, которые используют контейнер IoC для разрешения конкретных типов. Это должно быть достаточно просто, чтобы поменяться местами для набора стандартных фабрик. Это хороший подход? Кто-нибудь здесь использовал его и насколько хорошо он работал на вас? Есть ли что-нибудь еще?Аннотация завод шаблон на вершине IoC?

Спасибо!

ответ

69

Как вы уже выяснили, сам процесс инжекции (DI) сам по себе является лишь набором узоров и методов.

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

Дело в том, что в вашем приложении есть только одно место, где есть сильная ссылка на конкретную технологию (ваш контейнер DI). Остальная часть приложения блаженно не знают о как объект граф был подключен вверх - все, что имеет значение в том, что все необходимые зависимости были правильно введен (и вы можете использовать Constructor Injection с Null гвардейской, чтобы гарантировать, что это так).

Abstract Factory картина является очень полезный образец, когда дело доходит до DI. В сущности, используйте Abstract Factory, когда:

  • Вам необходимо указать один или несколько параметров, известных только во время выполнения, прежде чем вы сможете разрешить зависимость.
  • Срок службы зависимости концептуально короче срока службы потребителя.

Примеры и дополнительная информация доступна здесь:

+1

Я думаю, что я почти там. Оставайтесь со мной здесь :) Давайте просто скажем, что у меня интерфейс IFruit, который реализуется классом Apple. После регистрации этого конкретного типа я хочу использовать его в событии click button в форме Windows. Как мне попасть в класс Apple без явного доступа к контейнеру IoC из события кнопки? – 2010-01-03 18:29:26

+7

Это зависит: много ли примеров IFruit в вашем приложении или только один? Если есть только один, он уже должен быть введен в класс с помощью обработчика щелчка. Если их много, вам, скорее всего, понадобится IFruitFactory, который может создать экземпляр IFruit из других значений времени выполнения. В последнем случае IFruitFactory представляет собой инъекционную зависимость. –

+0

Учитывая, что существует только один экземпляр IFruit, единственный способ, которым я вижу его впрыскивание в класс Form с событием нажатия кнопки, - это изменить конструктор формы, чтобы включить интерфейс IFruit, а затем зарегистрировать сам Form с контейнером IoC для выполнения конструктора инъекции. Правильно ли это звучит? Спасибо за помощь! – 2010-01-03 19:27:16

4

В верхней части большей части вашего приложения вам понадобится класс Bootstrap, который загружает контекст IOC. Этот контекст затем предоставит фактически созданные объекты и, следовательно, станет фабрикой.

Но это должно происходить только с очень небольшим количеством объектов, и пользователь вашего класса Bootstrap/Factory должен знать как можно меньше о базовой архитектуре. Например, если вы полностью сконфигурировали объект HTTP-сервера через IOC, и вы хотите запустить его, ваш класс Bootstrap должен только предоставить метод getHttpServer(). Тогда вашему основному методу программы нужно только вызвать Bootstrap.getHttpServer(). Start(), чтобы запустить его.

Проводка других объектов уже выполнена с помощью контекста приложения, например. вы настраиваете объект A через IOC, который является частью объекта B, поэтому вы настраиваете объект B со ссылкой на объект A. Никому из них обычно не нужно знать ни о контейнере, ни о фабрике.

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