Dependency-Injection для разрешения циклических зависимостей - PullRequest
10 голосов
/ 09 апреля 2010

Пример:

class MyClass
{
    Composition m_Composition;

    void MyClass()
    {
        m_Composition = new Composition( this );
    }
}

Я заинтересован в использовании инъекции зависимостей здесь. Поэтому мне придется изменить конструктор на что-то вроде:

void MyClass( Composition composition )
{
    m_Composition = composition;
}

Однако сейчас у меня возникает проблема, поскольку Composition -объект опирается на только что созданный объект типа MyClass.

Может ли контейнер зависимостей разрешить это? Это должно быть сделано?
Или это просто плохой дизайн с самого начала?

1 Ответ

12 голосов
/ 11 апреля 2010

Нет , Контейнер DI не решит круговую зависимость - фактически, он будет протестовать против этого, вызывая исключения при попытке разрешить зависимости.

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

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

  • Используйте события для передачи сигналов от одного класса к другому. Часто круговая зависимость уже в основном идет в одном направлении, и в этом случае моделирование части этого API сигнализации в качестве событий может отрезать круг.
  • Если вышеприведенное верно, но вы чувствуете, что события кажутся неправильными, вы можете рассмотреть возможность применения шаблона Observer .
  • Если связь действительно должна идти в обоих направлениях, вы можете использовать Mediator , через который могут взаимодействовать компоненты.

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

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

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

...