Разрешение типа контейнера IOC и место впрыска - PullRequest
4 голосов
/ 29 июля 2010

Является ли наилучшей практикой разрешение и внедрение конкретных типов на границе модели домена, а затем их падение через домен? Например, если контейнер вводит конкретные типы в конструкторы контроллера MVC в веб-приложении или конечные точки службы в приложении на основе службы?

Мое понимание связности графов объектов-контейнеров немного странно.

Всегда ли уместно делать эквивалент Container.Resolve () в домене?

Ответы [ 2 ]

6 голосов
/ 29 июля 2010

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

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

Вы можете утверждать, что это означает, что вы просто создадите конкретные экземпляры изнутри потребителей, но лучшей альтернативой будет извлечение интерфейсов из этих типов (а затем их внедрение).

И нет: никогда не подходит для извлечения из контейнера из Модели Домена. Это анти-шаблон Service Locator . Голливудский принцип применяется и здесь:

Не вызывать контейнер; это позвонит тебе

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


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

Лучше обернуть мелкозернистый сервис в более грубый сервис. Я называю эти Совокупные услуги или Абстрактные фасады . Хотя они сами по себе будут иметь зависимости (например, упомянутые вами конечные точки службы), это будут подробности реализации . С точки зрения потребителя верхнего уровня, они не существуют.

Это не только хорошо решает проблему слишком большого числа зависимостей в конструкторе, но также помогает вам улучшить изоляцию между уровнями приложения.

2 голосов
/ 29 июля 2010

Ознакомьтесь с блогом Krzysztof Koźmic (s) на эту тему - я думаю, что у него есть несколько прекрасных мнений по этому поводу, и они в значительной степени суммируют то, что кажется текущей "лучшей практикой".

...