是否可以在程序集级别启用Visual Studio中的循环依赖项?相互依赖的组件是否可能?

时间:2010-07-03 01:21:18

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

这可能听起来像是一个愚蠢的问题,但无论如何我都会试一试。

因此在Visual Studio中,您不能有两个项目X和Y,以便X引用Y和Y引用X.

总的来说,由于种种原因,我完全可以理解循环依赖是如何产生问题的。

但是,以这种方式编译两个相互依赖的项目真的不是可能吗?在我看来它一定是可能的,因为(在我看来 - 也许我完全偏离此基础上)有两个相互依赖的程序集实际上不是所以与两个相互依赖的类不同 - 合法且可以编译的情况。

如果您说“两个程序集不能相互依赖,因为编译器无法在另一个程序集之前编译”,这对我来说是有意义的;除了看起来你可以为同一个程序集中的两个类创建相同的参数,显然编译器可以很好地处理这个场景。

基本上我问的原因并不是我有一些绝望的愿望去做这件事,我知道这一点通常是不明智的。具体来说,我想知道,因为如果我可以有两个项目 - 比如MyProjectCS和MyProjectVB - 基本上作为单个单元的两个相互依赖的部分存在,并且只是分开因为某些部分是用C#编写的,这将是很好的。其他部分都是用VB.NET编写的。

所以,我的问题是(yikes,three-fold):

  1. 是否可以启用此行为(在Visual Studio中或其他地方)?
  2. 如果在任何IDE中都不可能,至少理论上是否可能,或者可能存在相互依赖的程序集?
  3. 如果理论上不可能,为什么不呢?换句话说,相互依赖的程序集与单个程序集中的相互依赖的代码有何不同?

5 个答案:

答案 0 :(得分:12)

我不知道如何在IDE中执行此操作;但是有可能通过一个compilicated构建过程来构建。

您将需要:

  1. 装配A
  2. 装配B
  3. Stub Assembly B
  4. 其中Stub程序集B包含程序集B的公共类和公共方法以及相同的AssemblyInfo。*并引用相同的公钥。

    构建顺序:

    1. 编译存根装配B
    2. 将Stub Assembly B复制到Assembly B的输出目录
    3. 构建程序集A
    4. 构建程序集B
    5. 请注意,您不能对方法签名中的类型进行直接循环引用;但是你可以通过逐个对象来获得有效的循环。

      注:

      ilasm可以编译真正的相互递归程序集,因为它可以解析在编译时不存在的类型。

      继续:

      aspnet_compiler似乎能够在同一个项目中混合使用不同的语言(谁知道如何)。

答案 1 :(得分:6)

即使mscorlib.dll和System.dll程序集是相互依赖的,我建议永远不要让2个程序集相互依赖。

关于名称空间之类的hings之间的依赖循环,我建议使用NDepend来检测并避免使用dependency cycles

alt text

摘自文章(我写道):Control component dependencies to gain clean architecture

组件之间的依赖性循环导致通常称为意大利面条代码或纠结代码。如果组分A取决于取决于取决于A的C的B,则组分A不能独立于B和C进行开发和测试.A,B和C形成不可分割的单元,一种超级组分。由于规模现象的不经济性,这种超级组件的成本高于A,B和C的成本之和(在软件估算中有详细记载:Steve McConnell揭开黑暗艺术的神秘面纱)。基本上,这表明开发不可分割的代码片段的成本呈指数级增长。

这表明开发和维护1,000 LOC(代码行)可能比开发和维护500 LOC的成本高出三到四倍,除非它可以分成两个独立的500个LOC块。因此,与意大利面条的比较描述了无法维持的纠结代码。为了使架构合理化,必须确保组件之间没有依赖循环,还要检查每个组件的大小是否可接受(500到1000 LOC)。

答案 2 :(得分:2)

我不知道它在VB中是如何工作的,但理论上应该可以使用某种占位符指向另一个(生成非法代码)来编译其中一个,然后使用它来编译另一个,然后重新编译第一个。

例如,在编译需要彼此的程序时,循环依赖项解析就是这样的。

- 虽然通常是通过禁用尚不存在的功能来完成的

答案 3 :(得分:1)

如果使用命令行工具构建,则可以拥有包含许多模块的程序集。每个模块都可以使用不同的编译器进行编译。模块之间可以有循环依赖。

然而,我并不期望visiual studio能够支持这一点。


还有一些技巧可以告诉链接器将类型请求从一个程序集重定向到另一个程序集。 Microsoft使用它们然后在.net框架内移动类型。如果您无法让所有调用者重新编译代码,那么这只是有价值的。

答案 4 :(得分:0)

如果使用条件编译,则可以在Visual Studio中具有循环依赖关系。大多数情况下,最好删除循环引用,但如果您有充分的理由保留它们,this solution可以用作解决方法来构建它。