Dependency injection 解决循环依赖的依赖注入

Dependency injection 解决循环依赖的依赖注入,dependency-injection,refactoring,inversion-of-control,Dependency Injection,Refactoring,Inversion Of Control,例如: class MyClass { Composition m_Composition; void MyClass() { m_Composition = new Composition( this ); } } 我对使用依赖性注射感兴趣。因此,我必须将构造函数重构为: void MyClass( Composition composition ) { m_Composition = composition; } 但是现在我遇到了

例如:

class MyClass
{
    Composition m_Composition;

    void MyClass()
    {
        m_Composition = new Composition( this );
    }
}
我对使用依赖性注射感兴趣。因此,我必须将构造函数重构为:

void MyClass( Composition composition )
{
    m_Composition = composition;
}
但是现在我遇到了一个问题,因为
组合
-对象依赖于刚刚创建的
MyClass
类型的对象

依赖项容器可以解决这个问题吗?它应该这样做吗?

或者从一开始就是糟糕的设计?

,DI容器不会解决循环依赖关系——事实上,当您试图解决依赖关系时,它会抛出异常来抗议它

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

根据经验,循环依赖性是一种设计气味。如果可以,考虑另一种设计,去掉循环依赖性,这也会给你<强>更少的耦合< /强>。一些可能的重新设计备选方案:

  • 使用事件从一个类向另一个类发送信号。通常,循环依赖已经主要朝一个方向发展,在这种情况下,将此信令API的一部分建模为事件可能会切断循环
  • 如果上述情况属实,但你觉得事情似乎不对,你可以考虑应用这个模式。
  • 如果通信确实必须双向进行,则可以使用一个组件可以通过它进行通信的接口
然而,我特意选择了“气味”这个词而不是“反模式”,因为在某些情况下(特别是在处理外部定义的API时),循环依赖是无法避免的

在这种情况下,您需要决定在何处稍微放松依赖项的创建。一旦你知道了这一点,注入一个可能有助于推迟一个创造,直到圆的其他部分已经被创造出来


这是我目前所知道的最好的、可用的例子,但如果我可以大胆一点,我即将出版的书中也将包含一个章节来解决这个问题。

谢谢你的回答。我将尝试找出在我的例子中是否可以避免循环引用,尽管我不确定:我需要引用来订阅Composition构造函数中MyClass的一些事件。。。谢谢你提到你的书,听起来很有趣。我很期待阅读这本书。说得清楚一点:虽然你已经可以购买这本书的早期访问权,但是关于处理循环引用的部分还没有。在我看来,你描述它的方式,在这种情况下使用事件、观察者或中介模式是绕过循环依赖的黑客。如果,如你所说,耦合是不好的,并且依赖项(甚至是非循环的)导致耦合,为什么不完全取消依赖项,在一开始就使用观察者或中介模式呢?@poshest我不确定我是否遵循。。。如果你考虑观察者或中介者黑客(我不这样做),那么在开始时使用它们是如何改变的呢?“McSimuln对不起,我并不是说它们本身就是黑客,但是它们仅仅作为一种破坏循环依赖的方法而成为黑客。