Пример:
class MyClass
{
Composition m_Composition;
void MyClass()
{
m_Composition = new Composition( this );
}
}
Я интересуюсь использованием depenency-инжекции здесь. Таким образом, я должен буду осуществить рефакторинг конструктора к чему-то как:
void MyClass( Composition composition )
{
m_Composition = composition;
}
Однако я получаю проблему теперь, начиная с Composition
- объект полагается на объект типа MyClass
который просто создается.
Контейнер зависимости может разрешить это? Это, как предполагается, делает так?
Или это - просто плохой дизайн с начала на?
Нет , контейнер DI не решит циклическую зависимость - фактически, он будет протестовать против этого, выбрасывая исключения, когда вы пытаетесь разрешить зависимости.
Во многих контейнерах DI вы можете предоставить расширенную конфигурацию, которая позволяет решить эту проблему, но сами по себе они не могут разрешить циклические зависимости. Как они могли?
Как показывает практика, круговая зависимость - это запах дизайна . Если можете, рассмотрите альтернативный дизайн, в котором вы избавитесь от циклической зависимости - это также даст вам меньшее связывание . Некоторые возможные альтернативы перепроектирования:
Тем не менее, я намеренно выбрал слово запах вместо антипаттерн , поскольку есть угловые случаи (особенно когда вы имеете дело с внешне определенными API), когда невозможно избежать циклических зависимостей.
В таких случаях вам нужно решить, где немного ослабить создание зависимости. Как только вы это узнаете, внедрение абстрактной фабрики может быть полезным, чтобы отложить одно из творений до тех пор, пока не будут созданы другие части круга.
Этот другой ответ - лучший доступный пример, о котором я сейчас знаю, но если я буду таким смелым, моя будущая книга также будет содержать раздел, посвященный этой самой проблеме.