依赖注入可以防止循环依赖吗?
项目#1 具有项目#2 引用的一些接口和类。
现在我想在 Project#1 中使用 Project#2 的实现,但 vs.net 抱怨循环依赖。
如果我要在 Project#1 中使用依赖注入并绑定到 Project#2 中的实现(因为它遵守接口契约),这是否有效,或者我仍然会在运行时收到循环依赖错误消息?
Project#1 has some interfaces and classes that project#2 references.
Now I want to use the implementation of Project#2 in Project#1 but vs.net complains about a circular dependency.
If I was to use dependancy injection in Project#1 and bind to the implementation in Project#2 (since it adheres to the interface contract), will this work or I will still get the circular dependency error message at runtime?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能可以使用 DI 解决这个问题,但您不应该。
如果我理解正确的话,你会得到这样的结果:
换句话说,你试图让
MyClass
引用ConcreteFoo
,但你不能,因为程序集
已经依赖于ConcreteFoo
所在的 BA
中的IFoo
。这是一个设计错误。如果您在程序集
A
中声明接口IFoo
,但没有具体实现,则程序集A
中的任何其他接口/类应该仅引用IFoo
,从不实现它的具体类。可以通过三种方法消除循环依赖:
使
MyClass
依赖于IFoo
而不是ConcreteFoo
。如果你能做到的话,这可能是最好的选择。如果问题是您需要一个IFoo
的物理实例以在MyClass
中使用,并且不知道从哪里获取,那么让它采用一个IFoo
在构造函数中 - 让使用MyClass
的人弄清楚要使用什么IFoo
。将接口移动到它们自己的程序集中。这仍然是一个相当好的做法。您的设计将如下所示:
将
MyClass
移动到其自己的程序集。实际上,您的依赖关系树看起来与上面#2 中的相同,但如果程序集A
比B
小得多,那么这将需要更少的工作。希望有帮助。
You probably could solve this with DI, but you shouldn't.
If I understand correctly, you have something like this:
In other words, you're trying to get
MyClass
to referenceConcreteFoo
, but you can't because assemblyB
, whichConcreteFoo
resides in, already depends onIFoo
inA
.This is a design error. If you declare the interface
IFoo
in AssemblyA
, but no concrete implementations, then any other interfaces/classes in assemblyA
should only referenceIFoo
, never a concrete class that implements it.There are three ways to eliminate the circular dependency:
Make
MyClass
dependent onIFoo
instead ofConcreteFoo
. This is probably the best option if you can do it. If the issue is that you need a physical instance ofIFoo
for use inMyClass
and don't know where to get one from, then have it take anIFoo
in the constructor - let whoever usesMyClass
figure out whatIFoo
to use.Move the interfaces to their own assembly. This is still a reasonably good practice. Your design will look like this:
Move
MyClass
to its own assembly. Effectively your dependency tree will look the same as in #2 above, but if assemblyA
is much smaller thanB
then this would require less effort.Hope that helps.
您通常可以使用抽象工厂通过依赖注入 (DI) 解决循环依赖问题。请参阅这里是一个例子。
然而,虽然你也许能够通过 DI 解决问题,但最好重新设计 API 以消除循环依赖。
您通常可以通过将一端从基于查询的 API 更改为基于事件 API 来打破循环依赖关系。
You can often resolve circular dependency issues with Dependency Injection (DI) using an Abstract Factory. See here for an example.
However, although you may be able to solve the problem with DI, it would be better to redesign the API to make the circular dependency go away.
You can often break a circular dependency by changing one of the ends from a query-based API to an event-based API.
只要您仅在项目 1 代码中使用项目 1 中的类和接口,就可以了。 (我假设依赖项注入的配置是在项目 1 的代码库之外完成的。)
但我还必须说,任何循环依赖项的存在都会导致您质疑它为什么存在,并提示您思考其他问题解决问题的方法,从而消除它。
As long as you are only using classes and interfaces from Project 1 in Project 1 code, you will be fine. (I'm assuming that the configuration for the dependency injection is done outside of the codebase of Project 1.)
But I have to also say, the presence of any circular dependency should lead you to question why it exists, and prompt thought on other ways to solve the problem that removes it.