认识程序集:1. 程序集的生成
本文来源:http://www.cnblogs.com/netatomy/archive/2008/06/10/1216872.html
程序集(Assembly)是.NET程序的最小组成单位。每个程序集都有自己的名称、版本等信息。程序集通常表现为一个文件(.exe或.dll文件),这样的程序集被称为单文件程序集,这种程序集是最常见的。程序集也可以由多个文件组成,每个文件都是一个模块文件或者是一个资源文件,这样的程序集被称为多文件程序集。下面来了解一下如何生成单文件程序集和多文件程序集。
1. 单文件程序集的生成
这是最常见的程序集,使用 Visual Studio 只能生成单文件程序集。使用 csc.exe 能够很轻松地生成单文件程序集:
csc.exe /target:library /resource:Hello.jpg Hello.cs
上述命令执行后,会生成一个名为 Hello.dll 的文件,该文件组成了单文件程序集。这个文件是一个托管模块,存储了类型元数据和中间语言,还嵌入了资源文件 Hello.jpg 的内容(通过使用 /resource 选项)。类型元数据描述了模块中定义的类型及其成员,中间语言是编译后的托管代码。
程序集本身其实是一个逻辑概念,对于自身的描述是通过程序集清单来实现的。程序集清单是一种元数据,描述了程序集的名称、版本、区域性和强名称信息,还包括组成程序集的文件的列表和资源信息,以及其他信息。在单文件程序集中,程序集清单的元数据直接保存在主模块文件中。
在本例中,程序集中的名称是Hello,版本没有提供,默认为0.0.0.0,区域性为语言中立,强名称信息为空,文件列表只有Hello.exe,托管资源为Hello.jpg。
2. 多文件程序集的生成
多文件程序集比较少见,而且除了使用 csc.exe 之外,有时还需要使用 AL.exe。假设有两个源代码文件 A.cs 和 B.cs,我们有两种生成多文件程序集的方法,这两种方法的主要区别在于程序集清单是存储在某个模块中还是单独存储于主模块中。
先看第一种方法,只使用csc.exe就可以了:
csc.exe /target:module A.cs
csc.exe /target:library /addmodule.A.netmodule /out:Hello.dll B.cs
第一个命令将 A.cs 编译为一个模块文件,A.netmodule,该文件仅包含类型元数据和中间语言,不包含程序集清单,是一种“原始”的模块文件,不能独立存在,必须从属于程序集。第二个命令将 B.cs 编译成模块文件,Hello.dll。这个文件除了包含类型元数据和中间语言之外,还存储了程序集清单,因为成为主模块文件。此时,程序集的名称仍然为 Hello,但文件列表的内容变成了两个:A.netmodule 和 Hello.dll。
再来看第二种方法,需要使用 csc.exe 和 al.exe 两个命令:
csc /target:module A.cs
csc /target:module B.cs
al.exe /target:library /out:Hello.dll A.netmodule B.netmodule
前两个命令将 A.cs 和 B.cs 编译为两个“原始”的模块文件,A.netmodule 和 B.netmodule。第三个命令使用了AL.exe(Assembly Linker,程序集链接器),该命令能够将 A.netmodule 和 B.netmodule 组合到程序集中。这样,最终会生成 Hello.dll 这个主模块文件,该文件将仅包含程序集清单。在这个程序集清单中,文件列表的内容变成了三个:A.netmodule,B.netmodule 和 Hello.dll。
多文件程序集不仅生成麻烦,而且应用似乎也不是很广泛,因为对于CLR来说,它只认识程序集,所以部署的时候,都是以程序集作为最小单位。一旦某个“原始”模块发生了改变,整个程序集都必须重新生成。另外,只有程序集有版本,模块作为程序集的组成部分,不能被版本化。
通常,静态程序集可能由以下四个元素组成:
-
程序集清单,包含程序集元数据。
-
类型元数据。
-
实现这些类型的 Microsoft 中间语言 (MSIL) 代码。
-
资源集。
只有程序集清单是必需的,但也需要类型或资源来向程序集提供任何有意义的功能。
程序集中的这些元素有分组几种方法。您可以将所有元素分组到单个物理文件中,如下图所示。
单文件程序集
或者,可以将一个程序集的元素包含在几个文件中。这些文件可能是编译代码的模块 (.netmodule)、资源(例如 .bmp 或 .jpg 文件)或应用程序所需的其他文件。在您希望组合以不同语言编写的模块并优化应用程序的下载过程时,可创建一个多文件程序集,优化下载过程的方法是将很少使用的类型放入只在需要时才下载的模块中。
在下图中,一个假想应用程序的开发人员已选择将一些实用工具代码单独放入另一个模块中,同时在其原文件中保留一个较大的资源文件(在此例中为一个 .bmp 图像)。.NET Framework 只在文件被引用时下载该文件;通过将很少引用的代码保留在独立于应用程序的文件中来优化代码下载。
多文件程序集
注意 |
---|
构成多文件程序集的那些文件实际上并非由文件系统来链接。它们而是通过程序集清单进行链接,公共语言运行库将这些文件作为一个单元来管理。 |
在此插图中,所有三个文件均属于一个程序集,如 MyAssembly.dll 所包含的程序集清单文件中所述。对于该文件系统,这三个文件是三个独立的文件。请注意,文件 Util.netmodule 被编译为一个模块,因为它不包含任何程序集信息。在创建了程序集后,该程序集清单就被添加到 MyAssembly.dll,指示程序集与 Util.net 模块和 Graphic.bmp 的关系。
现在设计源代码时,您会作出有关如何将应用程序的功能划分到一个或多个文件的明确的决定。在设计 .NET Framework 代码时,您也将作出类似的决定,即如何将应用程序的功能划分到一个或多个程序集中。