项目#1 有一些项目#2 引用的接口和类。
现在我想在 Project#1 中使用 Project#2 的实现,但是 vs.net 抱怨循环依赖。
如果我要在 Project#1 中使用依赖注入并绑定到 Project#2 中的实现(因为它遵守接口契约),这是否可行,或者我仍然会在运行时收到循环依赖错误消息?
项目#1 有一些项目#2 引用的接口和类。
现在我想在 Project#1 中使用 Project#2 的实现,但是 vs.net 抱怨循环依赖。
如果我要在 Project#1 中使用依赖注入并绑定到 Project#2 中的实现(因为它遵守接口契约),这是否可行,或者我仍然会在运行时收到循环依赖错误消息?
你可能可以用 DI 解决这个问题,但你不应该.
如果我理解正确,你有这样的事情:
+ 装配 A + 装配 B | | +-- 接口 IFoo +-- 类 ConcreteFoo : IFoo | ^ +-- 类 MyClass -->-------->--------|
换句话说,您正在尝试访问MyClass
reference ConcreteFoo
,但您不能B
,因为驻留在其中的 assemblyConcreteFoo
已经依赖于IFoo
in A
。
这是一个设计错误。如果您IFoo
在 Assembly 中声明接口A
,但没有具体实现,则 assembly 中的任何其他接口/类都A
应该只引用IFoo
,而不是实现它的具体类。
消除循环依赖的三种方法:
使MyClass
依赖IFoo
而不是ConcreteFoo
. 如果可以的话,这可能是最好的选择。如果问题是您需要一个IFoo
用于使用的物理实例MyClass
并且不知道从哪里获得一个,那么让它IFoo
在构造函数中使用 - 让使用的人MyClass
弄清楚IFoo
要使用什么。
将接口移动到它们自己的程序集中。这仍然是一个相当好的做法。您的设计将如下所示:
+ 装配应用程序 + 装配接口 + 装配混凝土 | | | | +-- 接口 IFoo | | | \ | +-- 班级 MyClass | \------+-- 类 ConcreteFoo | | | ^ +---- 成员 Foo ->--------------------->-------- |
移动MyClass
到它自己的程序集。实际上,您的依赖关系树看起来与上面的 #2 相同,但如果程序集比上面A
的小得多,B
那么这将需要更少的工作。
希望有帮助。
您通常可以使用抽象工厂通过依赖注入 (DI) 解决循环依赖问题。有关示例,请参见此处。
然而,虽然你可以用 DI 解决问题,但最好重新设计 API 以消除循环依赖。
您通常可以通过将一端从基于查询的 API 更改为基于事件的API 来打破循环依赖关系。
只要您只在项目 1 代码中使用项目 1 中的类和接口,就可以了。(我假设依赖注入的配置是在项目 1 的代码库之外完成的。)
但我也不得不说,任何循环依赖的存在都应该让你质疑它为什么存在,并促使你思考解决问题的其他方法来消除它。