依赖注入:如何克服循环依赖
感谢您的阅读。
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这取决于您使用的(如果有)DI 框架。例如 Spring 只要不是每个涉及的 bean(对象)都由构造函数。基本上,它将一个空对象注入(至少)其他一个 bean 中,并稍后对其进行初始化。因此,顺序类似于:
这就是初始化的原因 -构造时不适用于此方法(因为初始化被推迟)。这确实是唯一的处理方法。好吧,也许您也可以使用某种代理(临时或永久)。
一般来说,至少根据我的经验,循环依赖是设计存在某种缺陷或需要简化的症状。
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:
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.
不要使服务* 依赖于另一个具体服务*。使它们依赖于超类或接口。然后在创建后将具体的 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.
我在某种程度上同意 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.