Внедрение зависимости: как преодолеть циклические зависимости - PullRequest
5 голосов
/ 13 февраля 2010

Спасибо за чтение.

Я использую инфраструктуру Unity для реализации внедрения зависимостей в моем приложении (ASP.Net MVC). Иногда существуют некоторые циклические зависимости между службами, которых я хочу избежать.

Так что я ищу решения:)


Мой кейс

хорошо, давайте представим 3 сервиса ServiceSally, ServiceJoe, ServiceJudy

ServiceSally зависит от ServiceJoe

ServiceJoe зависит от ServiceJudy

ServiceJudy зависит от ServiceSally (<< Это странно, не правда ли?) </p>

Так что если вы создаете экземпляр ServiceSally, ей понадобится ServiceJoe для инъекции, а ServiceJoe понадобится ServiceJudy и .... BANG! ... ServiceJudy потребуется ServiceSally, запускающая бесконечный цикл - и очень печальный любовный треугольник -.


Как я могу решить этот случай циклической любви-треугольника? : /

UPDATE:

Мое первое решение: The LazyJoe

Как насчет использования оболочки вокруг ссылок на сервисы для отсрочки внедрения до тех пор, пока они не будут использованы?

Что вы думаете?

Ответы [ 3 ]

7 голосов
/ 13 февраля 2010

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

  1. Создать сервисSally
  2. Создать ServiceJoe
  3. Создать ServiceJudy
  4. Инициализировать ServiceJudy
  5. Внедрить ServiceJudy в ServiceJoe
  6. Инициализировать ServiceJoe
  7. Внедрить ServiceJoe в ServiceSally
  8. Инициализировать ServiceSally
  9. Внедрить сервисSally в ServiceJudy
  10. Скажите ServiceJoe, ServiceJudy и ServiceSally, что они готовы

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

Вообще говоря, по крайней мере, по моему опыту, циклические зависимости являются симптомом конструкции, которая в некоторой степени имеет недостатки или нуждается в упрощении.

2 голосов
/ 14 февраля 2010

Не делайте Сервис * зависимым от другого конкретного Сервиса *.Сделайте их зависимыми от суперкласса или интерфейса.Затем внедрите конкретный Сервис * в другой Сервис * после создания.

0 голосов
/ 14 февраля 2010

Я согласен с Cletus в некоторой степени, когда вы обнаружите, что услуги зависят друг от друга, пришло время сесть и переосмыслить ваш дизайн.

Если вы делаете "ленивый DI", почему вы вообще делаете DI? Одно из преимуществ использования DI заключается в том, что вам не нужно беспокоиться о том, что ваши зависимости инициализированы, вы просто получаете их там, когда они вам нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...