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 ,而不是实现它的具体类。

有三种方法可以消除循环依赖:

  1. 使MyClass依赖于IFoo而不是ConcreteFoo 。 如果你能做到这一点,这可能是最好的选择。 如果问题是你需要在MyClass使用IFoo的物理实例并且不知道从哪里获取它,那么让它在构造函数中使用IFoo – 让任何使用MyClass都知道要使用的IFoo

  2. 将接口移动到自己的程序集。 这仍然是一个相当不错的做法。 您的设计将如下所示:

      +assemblyApp +assembly接口+assembly混凝土
       |  |  |
       |  +  - 接口IFoo |
       |  |  \ |
       +  -  MyClass类|  \ ------ +  - 类ConcreteFoo
       |  |  |  ^
       + ----会员Foo  - > ---------------------> ------------------- |
    
  3. MyClass移动到自己的程序集。 有效地,您的依赖树看起来与上面的#2相同,但如果程序集AB小得多,那么这将需要更少的工作量。

希望有所帮助。

您通常可以使用抽象工厂通过dependency injection(DI)解决循环依赖性问题。 请看这里的例子 。

但是,尽管您可以通过DI解决问题,但最好重新设计API以使循环依赖性消失。

您通常可以通过将基于查询的API中的一端更改为基于事件的 API来打破循环依赖。

只要您在Project 1代码中仅使用Project 1中的类和接口,就可以了。 (我假设dependency injection的配置是在Project 1的代码库之外完成的。)

但我还要说,任何循环依赖的存在都会引导你质疑它为什么存在,并提示其他方法来解决消除它的问题。