依赖注入来解决循环依赖 [英] Dependency-Injection to resolve circular dependencies

查看:168
本文介绍了依赖注入来解决循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例:

class MyClass
{
    Composition m_Composition;

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

我有兴趣在这里使用依赖注入。所以我必须重构构造函数,如下所示:

I am interested in using depenency-injection here. So I will have to refactor the constructor to something like:

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

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

However I get a problem now, since the Composition-object relies on the object of type MyClass which is just created.

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

或者从头开始只是糟糕的设计?

推荐答案

,DI容器不会解决循环依赖在尝试解决依赖关系时,将通过抛出异常来抗议它。

No, a DI Container will not solve a circular dependency - in fact, it will protest against it by throwing exceptions when you try to resolve the dependencies.

在许多DI容器中,您可以提供高级配置,使您能够克服此问题,但是他们自己不能解决循环依赖。他们怎么样?

In many of the DI Containers you can provide advanced configuration that allows you to overcome this issue, but by themselves they can't resolve circular dependencies. How could they?

根据经验,循环依赖是一种设计气味。如果可以,考虑一个替代设计,您可以摆脱循环依赖关系 - 这也将使您更少的耦合。一些可能的重新设计备选方案:

As a rule of thumb, a circular depedency is a design smell. If you can, consider an alternative design where you get rid of the circular dependency - this will also give you less coupling. Some possible redesign alternatives:


  • 使用事件将信号从一个类发送到另一个类。通常情况下,循环依赖性大部分在一个方向,而在这种情况下,将该信号API的部分建模作为事件可能会切割圆。

  • 如果上述是真的,但是感觉事件似乎错误,您可以考虑应用观察者模式。

  • 如果通信必须真正走到两方面,您可以使用中介者组件可以通信。

  • Use events to signal from one class to another. Often a circular dependency already mostly goes in one direction, and when this is the case, modeling part of this signaling API as events may cut the circle.
  • If the above is true, but you feel that events seem wrong, you can consider applying the Observer pattern.
  • If the communication must truly go both ways, you can use a Mediator through which the components can communicate.

但是,我反过来选择了 smell / em>,因为有角落的情况(特别是在处理外部定义的API时),其中循环依赖关系是无法避免的。

However, I purposedly chose the word smell over anti-pattern, as there are corner cases (particularly when you deal with externally defined APIs) where circular dependencies cannot be avoided.

在这种情况下,您需要确定哪里轻松放松依赖创造。一旦您知道,注入抽象工厂可能有助于推迟其中一项创作,直到圈子的其他部分已经创建。

In such cases, you need to decide where to loosen the dependency creation slightly. Once you know that, injection of an Abstract Factory may be helpful to defer one of the creations until the other parts of the circle have been created.

这个其他答案是我目前知道的最好的可用示例,但如果我可能是如此大胆,我即将出版的书还将包含一个解决这个问题的部分。

This other answer is the best, available example of which I'm currently aware, but if I may be so bold, my upcoming book will also contain a section that addresses this very issue.

这篇关于依赖注入来解决循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆