依赖注入(inject)解决循环依赖

标签 dependency-injection refactoring inversion-of-control

例子:

class MyClass
{
    Composition m_Composition;

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

我有兴趣在这里使用依赖注入(inject)。所以我将不得不将构造函数重构为:
void MyClass( Composition composition )
{
    m_Composition = composition;
}

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

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

最佳答案

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

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

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

  • 使用事件 从一个类(class)向另一个类(class)发出信号。通常,循环依赖已经大部分朝着一个方向发展,在这种情况下,将此信令 API 的一部分建模为事件可能会切断循环。
  • 如果上述情况属实,但您觉得事件似乎不对,您可以考虑申请 Observer图案。
  • 如果通信必须真正双向进行,您可以使用 Mediator组件可以通过它进行通信。

  • 但是,我特意选择了气味这个词而不是反模式,因为在某些极端情况下(特别是在处理外部定义的 API 时)无法避免循环依赖。

    在这种情况下,您需要决定在哪里稍微放松依赖创建。一旦你知道了,注入(inject) Abstract Factory将其中一个创建推迟到圆的其他部分创建之前可能会有所帮助。

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

    关于依赖注入(inject)解决循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2608875/

    相关文章:

    c# - 依赖注入(inject)——通过配置文件在运行时选择DLL和类实现

    c# - 如何在 Autofac 中为开放通用注册许多

    c# - 在 MVVM 中解耦 ViewModel

    javascript - Node.js、Express 和依赖注入(inject)

    java - SimpleMessageListenerContainer 中的构造函数注入(inject)

    angularjs - 将通用 Controller 功能提取到基本 Controller 中

    javascript - 如何从外部函数中分解出一个闭包,以便在不同的上下文中重用所述闭包?

    c# - 自动重构访问修饰符

    spring - Spring的@Autowired对象是否被重用?

    javascript - 创建新的 bindingContext 以供 subview 模型使用