在.NET基础类库之间存在循环引用:
-
System.dll
和System.Xml.dll
-
System.dll
和System.Configuration.dll
-
System.Xml.dll
和System.Configuration.dll
下面是从.net反射的屏幕截图,显示我的意思:
如何Microsoft创建这些组件是一个谜给我。 需要特殊的编译过程允许这样做? 我想一些有趣的事情是怎么回事。
在.NET基础类库之间存在循环引用:
System.dll
和System.Xml.dll
System.dll
和System.Configuration.dll
System.Xml.dll
和System.Configuration.dll
下面是从.net反射的屏幕截图,显示我的意思:
如何Microsoft创建这些组件是一个谜给我。 需要特殊的编译过程允许这样做? 我想一些有趣的事情是怎么回事。
我只能告诉Mono项目是如何做到这一点。 该定理是很简单,但它提供了代码的混乱。
他们首先编译System.Configuration.dll,而不需要部分的参考system.xml.dll的。 在此之后,他们编译system.xml.dll的正常方式。 现在到了魔术。 他们重新编译System.configuration.dll,与部分需要提及system.xml.dll的。 现在有一个成功的编译与循环引用。
简而言之:
RBarryYoung和Dykam是到一些东西。 Microsoft使用其使用ILDASM拆卸组件,去除所有内部/私有的东西和方法机构和重新编译IL(使用ILASM)转换成所谓的“脱水组件”或元数据组件内部工具。 这样做是每一个组件的公共接口改变时。
在构建,元数据组件代替以假乱真。 这样循环即碎。
这是可以做到Dykam描述的方式,但这样做,从它的Visual Studio块你。
你必须直接使用命令行编译器CSC.EXE。
CSC /目标:库ClassA.cs
CSC /目标:库ClassB.cs /reference:ClassA.dll
CSC /目标:库ClassA.cs ClassC.cs /reference:ClassB.dll
//ClassA.cs
namespace CircularA {
public class ClassA {
}
}
//ClassB.cs
using CircularA;
namespace CircularB {
public class ClassB : ClassA {
}
}
//ClassC.cs
namespace CircularA {
class ClassC : ClassB {
}
}
它很容易,只要你不使用项目引用在Visual Studio做...试试这个:
因此,这是你怎么做。 但严重的是...永远也不要做一个真正的项目! 如果你这样做,圣诞老人不会带给你任何礼物,今年。
我想这可能与非循环组组件的启动和使用ILMerge以合并,然后将较小的组件为逻辑上相关的一组来完成。
嗯,我从来没有做过它在Windows,但我已经做了上很多品种,用于其实际祖编译链接RTL环境。 你要做的就是首先使残余部分的“目标”,而不交叉引用然后链接,然后添加循环引用,然后重新连接。 连接物通常不关心圆形裁判或裁判之后链条,他们只关心能够解决它自己的每一个参考。
所以,如果你有两个库,A和B需要引用对方,尝试是这样的:
Dykam使得一个好点,这是编译,而不是在净链接,但原理是一样的:让你的交叉引用来源,他们出口的入口点,但有自己的引用他们的所有,但一到别人存根出。 建立他们这样。 然后,unstub外部引用和重建它们。 这应该工作,甚至无需任何特殊的工具,其实,这种做法,我曾经尝试过它(其中约6)每一个操作系统上工作。 虽然很明显的东西,它可以自动这将是一个很大的帮助。
一种可能的方法是使用条件编译(#如果)先编译System.dll中不依赖于所有这些组件,然后编译其他组件,最后重新编译System.dll中包括根据XML的零件和组态。
从技术上讲,这是可能的,这些并没有编译所有,并通过手工装配。 这是低层次库,毕竟。