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

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

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

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

但是,以这种方式编译两个相互依赖的项目真的不可能吗? 在我看来,它必须是可能的,因为(在我看来 – 也许我完全偏离这个)有两个相互依赖的程序集实际上没有两个相互依赖的类 – 一个案例合法的, 可以编译。

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

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

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

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

我不知道怎么在IDE中做到这一点; 然而,可以通过compilicated构建过程来构建。

你会需要:

  1. 大会A.
  2. 大会B.
  3. 存根组件B.

其中Stub程序集B包含程序集B的公共类和公共方法以及相同的AssemblyInfo。*并引用相同的公钥。

建造订单:

  1. 编译存根组件B.
  2. 将Stub Assembly B复制到Assembly B的输出目录
  3. 构建程序集A.
  4. 构建程序集B.

请注意,您不能在方法签名中具有类型的直接循环引用; 但是你可以通过对象进行强制循环。

注意:

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

进一步:

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

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

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

替代文字

摘自文章(我写的): 控制组件依赖关系以获得干净的架构

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

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

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

例如,循环依赖解析在编译需要彼此的程序时是如何工作的。

– 通常这是通过禁用尚不存在的function来完成的

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

但是我不希望visiual studio能够支持这个。


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

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