依赖注入以解决循环依赖关系

时间:2010-04-09 15:53:52

标签: dependency-injection refactoring inversion-of-control

示例:

class MyClass
{
    Composition m_Composition;

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

我有兴趣在这里使用depenency-injection。所以我必须将构造函数重构为:

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

但是我现在遇到了一个问题,因为Composition - 对象依赖于刚刚创建的MyClass类型的对象。

依赖容器可以解决这个问题吗?它应该这样做吗? 或者从一开始就是糟糕的设计?

1 个答案:

答案 0 :(得分:12)

,DI容器无法解决循环依赖 - 实际上,当您尝试解析依赖关系时,它会通过抛出异常来抗议它。

在许多DI容器中,您可以提供允许您克服此问题的高级配置,但它们本身无法解决循环依赖关系。他们怎么可能?

根据经验,循环依赖是设计气味。如果可以的话,考虑一个替代设计,你可以摆脱循环依赖 - 这也会给你更少的耦合。一些可能的重新设计方案:

  • 使用事件从一个班级向另一个班级发出信号。通常,循环依赖已经主要朝向一个方向,并且在这种情况下,将此信令API的一部分建模为事件可能会削减圆圈。
  • 如果上述情况属实,但您认为事件似乎有误,可以考虑应用Observer模式。
  • 如果通信必须真正双向进行,您可以使用组件可以通过的Mediator进行通信。

然而,我有意选择嗅觉这个词而不是反模式,因为有一些极端情况(特别是当你处理外部定义的API时)循环依赖不能避免。

在这种情况下,您需要稍微决定放松依赖关系创建的位置。一旦你知道这一点,注入Abstract Factory可能有助于推迟其中一个创作,直到创建了圆圈的其他部分。

这个other answer是我目前所知道的最好的,可用的例子,但如果我可能如此大胆,我即将出版的书也将包含一个解决这个问题的部分。