代码改变世界

3.4 在生成的程序集中引用一个强命名程序集

2011-12-05 14:55  iRead  阅读(504)  评论(0编辑  收藏  举报

  任何时候生成一个程序集,程序集都会包含对其他强命名程序集的引用。之所以这样说,是因为System.Object是在MSCorLib.dll中定义的,后者就是一个强命名的程序集。除此之外,在你的程序集中,还可以引用由Microsoft、第三方厂商或你自己公司开发的其他强命名程序集。第2章介绍了如何使用CSC.exe的/reference编译器开关来指定想要引用的程序集文件名。如果文件名是一个完整路径,CSC.exe会加载指定的文件,并根据它的元数据来生成程序集。如第2章所述,如果指定的是一个不包含路径的文件名,CSC.exe会尝试在以下目录查找程序集(按所列顺序):

  1. 工作目录
  2.  包含CSC.exe本身的目录,目录中还包含CLR的各种DLL文件
  3. 使用/lib编译器开关指定的任何目录
  4. 使用LIB环境变量指定的任何目录

  所以,如果生成的程序集引用了Microsoft的System.Drawing.dll,可在执行CSC.exe时使用/reference:System.Drawing.dll开关。编译器会依次检查上述目录,并在CSC.exe自己所在的目录(%SystemRoot%\Microsoft.NET\Framework\v4.0.#####)找到System.Drawing.dll文件。在同一个目录中,还存储了编译器所对应的那个版本的CLR所支持的各种DLL文件。虽然编译器会在这里寻找程序集,但运行时从不会从这里加载程序集。

  安装.NET Framework时,实际会安装Microsoft的程序集文件的两套拷贝。一套安装到编译器/CLR目录,另一套安装到一个GAC子目录。编译器/CLR目录中的文件方便你生成程序集,而GAC中的拷贝方便在运行时加载。

  CSC.exe编译器之所以不在GAC中查找引用的程序集,是因为你必须知道程序集的路径,但GAC的结构又没有正式公开。另外,作为一个替代方案,CSC.exe允许指定一个依然比较长但比较容易阅读的字符串,比如”System.Drawing,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5ftf11d50a3a”。这两个方案都不如在用户的硬盘上安装两套一样的程序集文件。

注意:生成一个程序集时,它引用的一个程序集可能同时存在x86和x64版本。幸好,GAC下面的子目录完全能够容纳同一个程序集的x86和x64版本。但是,由于程序集具有相同的文件名,所以不能将这种程序集的不同版本安装到编译器/CLR目录中去。然而,这应该没有什么影响。在一台机器上安装.NET Framework时,会将程序集的x86和x64或IA64版本安装到GAC中。生成程序集时,可引用已安装的任何版本的文件,因为所有版本都包含完全一致的元数据,有区别的只是它们的代码。在运行时,则会从GAC中加载正确版本的程序集。本章稍后会讨论在运行的时候,CLR如何决定该从什么位置加载程序集。