.NET模块与大会

我一直试图把我的头围绕“正确的”答案呢? 有几个关于这个覆盖的stackoverflow的主题,但与msdn文档有点冲突。

例如,请注意第二个问题的答案: 什么是托pipe模块(与组件相比)?

现在看看msdn图表: http : //msdn.microsoft.com/en-us/library/zst29sk2( VS.100) .aspx

msdn图意味着一个单一的文件组件不包含一个模块,而是一个清单,il代码,types元数据等等。这与我读过的许多其他文章不同,它指出单个文件程序集有一个模块。

答案是什么? 如果答案是“两个”,那么模块是一个单独的物理文件,通过程序集清单链接?

每个组件至less有一个模块。 这是一个高度隐形的实现细节。 但是当你使用Reflection.Emit的时候你可以看到它。 从AssemblyBuilder类的示例代码:

AssemblyName aName = new AssemblyName("DynamicAssemblyExample"); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly( aName, AssemblyBuilderAccess.RunAndSave); // For a single-module assembly, the module name is usually // the assembly name plus an extension. ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); TypeBuilder tb = mb.DefineType( "MyDynamicType", TypeAttributes.Public); 

注意使用ModuleBuilder类,types被添加到模块中。 一个程序集可以包含多个模块是非常不相关的,构build环境不支持它。 不只是IDE,MSBuild也不支持它。 您必须自己编写一个构build脚本才能使用程序集链接器al.exe 。 没有很好的理由这样做,我可以想到,所有的.NET编译器已经知道如何直接生成一个单一的模块组装。 Al.exe是一个典型的引导工具,可能用于构buildmscorlib.dll。

在.NET中,程序集和模块之间的区别在于模块不包含清单

 //Copied from CLR via C# 

什么是明显的?

清单是另一组元数据表,基本上包含作为程序集一部分的文件的名称。 他们还描述了程序集的版本,文化,发布者,公开导出的types以及构成程序集的所有文件。

CLR在组件上运行; 也就是说,CLR总是首先加载包含清单元数据表的文件,然后使用清单来获取程序集中其他文件/模块的名称。

如何组合模块来组装一个assembly体?

使用C#编译器

要理解如何构build一个多文件/多模块程序集,我们假设我们有两个源代码文件:

RUT.cs包含很less使用的types

FUT.cs包含经常使用的types

我们将很less使用的types编译到它们自己的模块中,这样如果程序集的用户从不访问那些很less使用的types,那么程序集的用户就不需要部署这个模块。

 csc /t:module RUT.cs 

此行使C#编译器创build一个RUT.netmodule文件。 这个文件是一个标准的DLL PE文件,但是,CLR本身不能加载它。 接下来,让我们将常用的types编译到自己的模块中。 我们将使这个模块成为程序集清单的守护者,因为types经常使用。 实际上,因为这个模块现在将代表整个程序集,所以我会将输出文件的名称更改为MultiFileLibrary.dll,而不是将其称为FUT.dll。

 csc /out:MultiFileLibrary.dll /t:library /addmodule:RUT.netmodule FUT.cs 

此行通知C#编译器编译FUT.cs文件以生成MultiFileLibrary.dll文件。 由于指定了/ t:library,因此包含清单元数据表的DLL PE文件被发送到MultiFileLibrary.dll文件中。 /addmodule:RUT .netmodule开关告诉编译器RUT.netmodule是一个应该被认为是程序集的一部分的文件。 具体来说, /addmodule开关告诉编译器将文件添加到FileDef清单元数据表中,并将RUT.netmodule的公共导出types添加到ExportedTypesDef清单元数据表中。

编译器完成所有处理后,将创build如图2-1所示的两个文件。 右侧的模块包含清单。

在这里输入图像说明

使用assembly链接器

AL.exe实用程序可以生成一个EXE或DLL PE文件,其中只包含描述其他模块中的types的清单。 为了理解AL.exe是如何工作的,我们来改变MultiFileLibrary.dll程序集的构build方式。

 csc /t:module RUT.cs csc /t:module FUT.cs al /out: MultiFileLibrary.dll /t:library FUT.netmodule RUT.netmodule 

图2-3显示了执行这些语句所产生的文件。

在这里输入图像说明

我build议您阅读Jeffrey Richter的 第2章: 通过C# 构build,打包,部署和pipe理 CLR中的 应用程序和types ,以便详细了解这个概念。

模块是程序集内代码的逻辑集合。 你可以在一个Assembly中有多个模块,每个模块都可以用不同的.NET语言编写(就我所知,VS不支持创build多模块程序集)。

组件包含模块。 模块包含类。 类包含函数。

从: 什么是.NET中的模块?

真的来自:Bingsearch“.NET模块与程序集”