什么是循环依赖,我该如何解决?

时间:2016-06-26 19:01:44

标签: c# .net vb.net visual-studio circular-dependency

方案

我有一个解决方案,我有(超过)2个项目。

第一个项目有一个项目引用第二个项目。第二个项目没有引用第一个项目。

好吧,在第一个项目中,我定义了一个可继承的类类型,我希望第二个项目中的某些类继承它。

问题

显然,如果我想继承第一个项目中定义的类型,在第二个项目中,我需要向第一个项目添加项目引用,以便能够看到类型并继续。

问题是,当我尝试添加项目引用时,收到此错误消息:

Circular dependency error

问题

有人可以用其他简单的词语解释我(也许在代码的例子中也隐含在错误中)什么是循环依赖?,最重要的是:我能做些什么来解决它? (请在回答之前阅读我研究的最后一部分)。

研究

我第一次听到“&em> 循环依赖&#34 ;;我已阅读MSDN中的 this 文章,但我理解没有

无论如何,我看到很多关于循环依赖的问题,比如 this ,而且从我在该问题中看到的情况看来,循环依赖意味着两个项目无法在它们之间引用同时,这两个项目中只有一个可以引用另一个; 并且在那个问题中回答的所有人都说过" 重新设计就是解决方案"或者" 循环依赖不是好的做法"但是,在我的案例中重新设计将意味着在两个项目中定义相同的类型,我不认为既不是好的做法,当然也只是建立一个额外的程序集/项目来存储一个类型来引用两个项目中的程序集......这是我认为最糟糕的想法。

4 个答案:

答案 0 :(得分:12)

循环依赖是项目A依赖于项目B中的某些内容而项目B依赖于项目A中的某些内容。这意味着要编译项目A,您必须首先编译项目B,但是您不能这样做,因为B需要A要编译。这是循环依赖导致的问题。

如果为已经构建的项目引入循环依赖项,则很难发现,因为标准构建选项不会删除现有的目标文件,因此可以首先构建A(或B)。你只会在尝试使用之前从未构建解决方案的其他机器上或者如果你做一个干净的&建立。

  在我的案例中重新设计将意味着在两个项目中定义相同的类型,我认为这也不是好的做法。

在这种情况下,您需要创建第三个项目“C”,其中包含A和B所依赖的类,因此它们不再相互依赖。您可能只需将类拆分,以便可以按照这种方式对依赖项进行排序,而无需创建第三个项目。

答案 1 :(得分:9)

什么是依赖?

为了理解循环依赖是什么,最好理解什么是依赖性以及它对编译器意味着什么。

假设您有一个项目,并且在课堂上,您已定义以下内容:

Public Class MyClass
    'Some code here
    Private MyString As String
    'Some code there
End Class

编译项目时,编译器会运行String类,该类在名为System的DLL文件中定义。然后它会将该DLL链接到您的项目,因此在运行时,在对字符串进行定义或操作时,将加载System.dll以执行这些操作。

现在,假设您的课程中还有以下定义

'Some code here
Private MyObjet as CustomClass1
'Some code there

让我们说CustomClass1在你的另一个项目中定义,命名为Project2.DLL:

Public Class CustomClass1
    'Your customr class code
End Class

因此,在编译第一个项目时,编译器将运行CustomClass1定义,它知道它放入Project2.dll,因此之前将编译Project2,以便能够在第一个项目中添加该引用

这就是一种依赖,它是等级的,必须有一个起点。甚至String类依赖于其他类,最后,它们都依赖于字节或位来完成工作,因为这是计算机可以做的唯一事情,可以使用10

所以圆形部分

因此,如果您在Project2中有一个链接到第一个项目的引用(字段定义或类似内容),会发生什么?

  • 编译器会读取您的第一个项目,然后运行到CustomClass1
  • 然后它尝试编译Project2,因为在那里定义了CustomClass1
  • 然后它会运行到第一个项目中定义的类
  • 它尝试编译您的第一个项目,以便将其链接到第二个
  • 然后它将运行到CustomClass1
  • 然后它尝试编译Project2
  • 我猜你明白了......

所以在某些时候编译器显示错误,说它无法编译,因为它不明白你要做什么...

是的,电脑是那么愚蠢。

如何解决?

解决这类问题有时很困难,但基本思想是建立一个层次结构,将基类(不需要依赖的基类)放在一起,然后在它们上构建。

将所有依赖于彼此的类放在一起,它们形成了一个层,用于您尝试在应用程序中执行的操作。

答案 2 :(得分:1)

我知道修复 CD 的最简单方法是创建一个 PROJECT-of-Interfaces,并使 CD 中涉及的项目引用 PROJECT-of-interfaces,而不是相互引用。 有点乱,但很管用。

答案 3 :(得分:-1)

不是使用项目作为引用,而是使用该项目的构建DLL进行引用。.如果在解决方案的每个模块中都执行相同操作,则可以解决该问题。 如果您有两个名为“ main”和“ sub”的项目 然后在主项目中添加子项目的DLL作为参考文件,同时在Sub项目中添加主项目的DLL作为参考。