3

项目#1 有一些项目#2 引用的接口和类。

现在我想在 Project#1 中使用 Project#2 的实现,但是 vs.net 抱怨循环依赖。

如果我要在 Project#1 中使用依赖注入并绑定到 Project#2 中的实现(因为它遵守接口契约),这是否可行,或者我仍然会在运行时收到循环依赖错误消息?

4

3 回答 3

15

你可能可以用 DI 解决这个问题,但你不应该.

如果我理解正确,你有这样的事情:

  + 装配 A + 装配 B
  | |
  +-- 接口 IFoo +-- 类 ConcreteFoo : IFoo
  | ^
  +-- 类 MyClass -->-------->--------|

换句话说,您正在尝试访问MyClassreference ConcreteFoo,但您不能B,因为驻留在其中的 assemblyConcreteFoo已经依赖于IFooin A

这是一个设计错误。如果您IFoo在 Assembly 中声明接口A,但没有具体实现,则 assembly 中的任何其他接口/类都A应该引用IFoo,而不是实现它的具体类。

消除循环依赖的三种方法:

  1. 使MyClass依赖IFoo而不是ConcreteFoo. 如果可以的话,这可能是最好的选择。如果问题是您需要一个IFoo用于使用的物理实例MyClass并且不知道从哪里获得一个,那么让它IFoo在构造函数中使用 - 让使用的人MyClass弄清楚IFoo要使用什么。

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

      + 装配应用程序 + 装配接口 + 装配混凝土
      | | |
      | +-- 接口 IFoo |
      | | \ |
      +-- 班级 MyClass | \------+-- 类 ConcreteFoo
      | | | ^
      +---- 成员 Foo ->--------------------->-------- |
    
  3. 移动MyClass到它自己的程序集。实际上,您的依赖关系树看起来与上面的 #2 相同,但如果程序集比上面A的小得多,B那么这将需要更少的工作。

希望有帮助。

于 2010-01-12T23:31:13.537 回答
8

您通常可以使用抽象工厂通过依赖注入 (DI) 解决循环依赖问题。有关示例,请参见此处。

然而,虽然你可以用 DI 解决问题,但最好重新设计 API 以消除循环依赖。

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

于 2010-01-12T23:05:22.423 回答
1

只要您只在项目 1 代码中使用项目 1 中的类和接口,就可以了。(我假设依赖注入的配置是在项目 1 的代码库之外完成的。)

但我也不得不说,任何循环依赖的存在都应该让你质疑它为什么存在,并促使你思考解决问题的其他方法来消除它。

于 2010-01-12T22:51:19.390 回答