dependency injection可以防止循环依赖吗?
项目#1有一些项目#2引用的接口和类。
现在我想在Project#1中使用Project#2的实现,但vs.net抱怨循环依赖。
如果我在Project#1中使用dependency injection并绑定到Project#2中的实现(因为它遵守接口契约),这是否可行或者我仍然会在运行时获得循环依赖性错误消息?
你可能用DI 来解决这个问题,但你不应该这样做 。
如果我理解正确,你有这样的事情:
+assemblyA +assemblyB. | | + - 接口IFoo + - 类ConcreteFoo:IFoo | ^ + - MyClass类 - > -------> ------- |
换句话说,你试图让MyClass
引用ConcreteFoo
,但你不能,因为ConcreteFoo
所在的程序集B
已经依赖于A
IFoo
。
这是一个设计错误。 如果在程序集A
声明接口IFoo
,但没有具体实现,那么程序集A
任何其他接口/类应该只引用IFoo
,而不是实现它的具体类。
有三种方法可以消除循环依赖:
-
使
MyClass
依赖于IFoo
而不是ConcreteFoo
。 如果你能做到这一点,这可能是最好的选择。 如果问题是你需要在MyClass
使用IFoo
的物理实例并且不知道从哪里获取它,那么让它在构造函数中使用IFoo
– 让任何使用MyClass
都知道要使用的IFoo
。 -
将接口移动到自己的程序集。 这仍然是一个相当不错的做法。 您的设计将如下所示:
+assemblyApp +assembly接口+assembly混凝土 | | | | + - 接口IFoo | | | \ | + - MyClass类| \ ------ + - 类ConcreteFoo | | | ^ + ----会员Foo - > ---------------------> ------------------- |
-
将
MyClass
移动到自己的程序集。 有效地,您的依赖树看起来与上面的#2相同,但如果程序集A
比B
小得多,那么这将需要更少的工作量。
希望有所帮助。
您通常可以使用抽象工厂通过dependency injection(DI)解决循环依赖性问题。 请看这里的例子 。
但是,尽管您可以通过DI解决问题,但最好重新设计API以使循环依赖性消失。
您通常可以通过将基于查询的API中的一端更改为基于事件的 API来打破循环依赖。
只要您在Project 1代码中仅使用Project 1中的类和接口,就可以了。 (我假设dependency injection的配置是在Project 1的代码库之外完成的。)
但我还要说,任何循环依赖的存在都会引导你质疑它为什么存在,并提示其他方法来解决消除它的问题。