依赖注入:如何克服循环依赖

时间:2010-02-13 20:45:16

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

感谢阅读。

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

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


我的情况

好吧,让我们想象3服务ServiceSally,ServiceJoe,ServiceJudy

ServiceSally依赖于ServiceJoe

ServiceJoe依赖于ServiceJudy

ServiceJudy依赖于ServiceSally(<<那有点奇怪不是吗?)

因此,如果您实例ServiceSally,她将需要注入ServiceJoe,而ServiceJoe将需要ServiceJudy和.... BANG!... ServiceJudy将需要ServiceSally启动无限循环 - 非常悲伤的三角形 - 。


我怎么能解决这个循环爱三角形的情况? :/

更新:

我的第一个解决方案:LazyJoe

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

您怎么看?

3 个答案:

答案 0 :(得分:7)

这取决于您正在使用的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他们已经准备好了
  11. 这就是为什么初始化构造不能用于此方法(因为初始化是延迟的)。这是处理它的唯一方法。好吧也许你也可以使用某种代理(临时或永久)。

    一般来说,至少根据我的经验,循环依赖性是一种设计的症状,这种设计在某种程度上存在缺陷或需要简化。

答案 1 :(得分:2)

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

答案 2 :(得分:-2)

我同意Cletus在某种程度上,只要你发现自己有相互依赖的服务,就该坐下来重新考虑你的设计。

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

相关问题