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

发布于 2024-08-21 20:13:20 字数 628 浏览 6 评论 0原文

感谢您的阅读。

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

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


我的案例

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

ServiceSally 依赖于 ServiceJoe

ServiceJoe 依赖于 ServiceJudy

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

所以,如果你实例ServiceSally,她将需要注入ServiceJoe,而ServiceJoe将需要ServiceJudy,并且......砰!...ServiceJudy将需要ServiceSally开始一个无休止的循环 - 以及非常悲伤的三角恋 - 。


我该如何解决这个循环三角恋案例? : /

更新:

我的第一个解决方案:LazyJoe

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

你怎么认为?

Thanks for reading.

I'm using Unity framework to implement dependency injection in my app (ASP.Net MVC).
Sometimes there are some cyclic dependencies among services that I want to avoid.

So I'm looking for solutions : )


My case

well lets imagine 3 services ServiceSally, ServiceJoe, ServiceJudy

ServiceSally depends on ServiceJoe

ServiceJoe depends on ServiceJudy

ServiceJudy depends on ServiceSally (<< That is kind of weird isn't it?)

So if you instance ServiceSally, she will need ServiceJoe to be injected, and ServiceJoe will need ServiceJudy and.... BANG!... ServiceJudy will need ServiceSally starting an endless cycle -and very sad love triangle-.


How could I solve this cyclic-loveTriangle case? : /

UPDATE:

My first solution: The LazyJoe

What about to use a wrapper around the services references to delay the injection until they are used?

What do you think?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你的往事 2024-08-28 20:13:20

这取决于您使用的(如果有)DI 框架。例如 Spring 只要不是每个涉及的 bean(对象)都由构造函数。基本上,它将一个空对象注入(至少)其他一个 bean 中,并稍后对其进行初始化。因此,顺序类似于:

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

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

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

This depends on what (if any) DI framework you're using. Spring for example will handle this kind of cyclic dependency as long as not every involved bean (object) is initialized by a constructor. Basically it injects an empty object into (at least) one of the other beans and initializes it later. So the sequence is something like:

  1. Create a ServiceSally
  2. Create a ServiceJoe
  3. Create a ServiceJudy
  4. Initialize ServiceJudy
  5. Inject ServiceJudy into ServiceJoe
  6. Initialize ServiceJoe
  7. Inject ServiceJoe into ServiceSally
  8. Initialize ServiceSally
  9. Inject ServiceSally into ServiceJudy
  10. Tell ServiceJoe, ServiceJudy and ServiceSally that they're ready

This is why initialization-on-construction won't work with this method (because initialization is deferred). It's really the only way to handle it. Well maybe you could use some kind of proxy (temporary or permanent) too.

Generally speaking, at least in my experience, cyclic dependencies are symptomatic of a design that is either flawed in some way or in need of simplification.

神爱温柔 2024-08-28 20:13:20

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

Don't make a Service* dependent on another concrete Service*. Make them dependent on a superclass or interface. Then inject a concrete Service* into another Service* after creation.

简单 2024-08-28 20:13:20

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

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

I agree with Cletus to some extend, whenever you find yourself having services depend on one another it's time to sit down and rethink your design.

If you do "lazy DI", why are you doing DI at all? One of the benefits of using DI is not having to worry when your dependencies are initialized, you just have them there when you need them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文