【问题标题】:Dependecy Injection: How To Overcome Cyclic Dependencies依赖注入:如何克服循环依赖
【发布时间】:2010-02-13 20:45:16
【问题描述】:

感谢阅读。

我正在使用 Unity 框架在我的应用程序 (ASP.Net MVC) 中实现依赖注入。 有时我想避免服务之间存在一些循环依赖关系。

所以我正在寻找解决方案:)


我的情况

让我们想象一下 3 个服务 ServiceSally、ServiceJoe、ServiceJudy

ServiceSally 依赖于 ServiceJoe

ServiceJoe 依赖于 ServiceJudy

ServiceJudy 依赖于 ServiceSally(

因此,如果您实例化 ServiceSally,她将需要注入 ServiceJoe,而 ServiceJoe 将需要 ServiceJudy 并且.... BANG!... ServiceJudy 将需要 ServiceSally 开始一个无休止的循环 - 以及非常可悲的三角恋 -。


我该如何解决这个 cyclic-loveTriangle 案例? :/

更新:

我的第一个解决方案:LazyJoe

如何在服务引用周围使用包装器来延迟注入直到它们被使用?

你怎么看?

【问题讨论】:

    标签: design-patterns dependency-injection unity-container


    【解决方案1】:

    这取决于您使用的是什么(如果有)DI 框架。例如Spring 将处理这种循环依赖,只要不是每个涉及的 bean(对象)都由构造函数初始化。基本上,它将一个空对象注入(至少)一个其他 bean 并稍后对其进行初始化。所以顺序是这样的:

    1. 创建 ServiceSally
    2. 创建 ServiceJoe
    3. 创建 ServiceJudy
    4. 初始化ServiceJudy
    5. 将 ServiceJudy 注入 ServiceJoe
    6. 初始化 ServiceJoe
    7. 将 ServiceJoe 注入 ServiceSally
    8. 初始化 ServiceSally
    9. 将 ServiceSally 注入 ServiceJudy
    10. 告诉 ServiceJoe、ServiceJudy 和 ServiceSally 他们准备好了

    这就是为什么构造时初始化不适用于此方法的原因(因为初始化被延迟)。这确实是处理它的唯一方法。好吧,也许您也可以使用某种代理(临时或永久)。

    一般来说,至少根据我的经验,循环依赖是设计在某些方面存在缺陷或需要简化的症状。

    【讨论】:

    • 嗨 Cletus,感谢您的回答:) +1 我正在使用 Unity。你是对的,我认为可能需要简化.. 但在项目生命的这一点上,它会被推迟一段时间; ) 尊重 Spring 的方式来做到这一点......那么使用惰性 DI 是个好主意吗? : 哦
    • 在第 9 步。没有为 ServiceJudy 创建 ServiceSally 实例,因为第 3 步完成了所有对象创建阶段,对吗? : 哦
    • SD":在这种情况下,懒惰的 DI 并不是一个好主意,它只是唯一的选择。
    • +1 表示“一般来说......循环依赖是设计存在缺陷......或需要简化的症状。”在某些特定的、罕见的情况下,循环依赖可能是问题的最佳解决方案,但这种情况很少见。
    • 我写了自己的依赖注入器来处理循环依赖。也许我应该只使用 Spring,但是对于我自己的项目来说,Spring 听起来有点“重量级”,而且我反对使用 xml 文件编写代码。我的注射器在这里:hughperkins.com/easyinjector
    【解决方案2】:

    不要让服务* 依赖于另一个具体的服务*。使它们依赖于超类或接口。然后在创建后将一个具体的 Service* 注入到另一个 Service* 中。

    【讨论】:

    • 感谢您的解决方案 Ozan! +1 非常有创意:D
    【解决方案3】:

    我在某种程度上同意 Cletus 的观点,每当您发现自己的服务相互依赖时,就该坐下来重新考虑您的设计了。

    如果你做“懒惰的 DI”,你为什么还要做 DI?使用 DI 的好处之一是在初始化依赖项时不必担心,您只需在需要它们时将它们放在那里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-14
      • 2018-03-03
      • 2010-11-29
      • 2018-09-03
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      相关资源
      最近更新 更多