程序集,简单来说就是一个以公共语言运行库(CLR)为宿主的,版本化的,自描述的二进制文件,虽然现实中的.NET程序集与Win32二进制文件的的扩展名相同(*.exe或*.dll),但是两者的内部构成几乎完全不同。C#程序集具有如下有点:使用命名空间确定类型边界;可版本化;是自描述的(不需要访问注册表来定位);是可配置的。
C#学习笔记-程序集
罗朝辉(http://www.cnblogs.com/kesalin/)
《C#与.NET高级程序设计》读书笔记
1,程序集,简单来说就是一个以公共语言运行库(CLR)为宿主的,版本化的,自描述的二进制文件,虽然现实中的.NET程序集与Win32二进制文件的的扩展名相同(*.exe或*.dll),但是两者的内部构成几乎完全不同。C#程序集具有如下有点:使用命名空间确定类型边界;可版本化;是自描述的(不需要访问注册表来定位);是可配置的。
2,程序集的格式包括如下几个部分:Win32文件首部;CLR文件首部;CIL代码;类型元数据;程序集清单;可选的嵌入资源。我们可以使用 dumpbin.exe 来查看Win32文件首部和CLR文件首部,使用 ildasm.exe 或 reflector.exe来查看程序集的CIL代码,元数据或清单。
Win32文件首部:它使程序集可以被Windows系统加载或操作;
CLR文件首部:它定义多个标记,使得运行库可以了解到托管文件的布局。这些标记标识了文件中元数据和资源的位置,程序集构建的运行版本,(可选的)公钥值等。
CIL代码:CIL代码是程序集的核心部分, 且是独立于平台和CPU的中间语言。在运行时,程序集内部的CIL代码才被(实时的JIT编译器)编译成特定平台和CPU的指令。正是这样的机制,保证.NET程序集的跨平台,跨语言。
元数据:它完整地描述了程序集内含类型和引用外部类型的格式。运行库利用元数据在内存的二进制布局类型中解析类型(以及类型的成员)的位置,使远程方法调用更便利。此外,程序集必须被关联一个manifest,该清单详细记录了程序集中的每一个模块,构建程序集的版本以及该程序集引用的所有外部程序集。
可选的嵌入资源:嵌入资源可包括应用程序图标,图像,声音或字符串表,还支持附属程序集(只包含本地化资源)。
3,单文件程序集的所有必要部分(首部信息,CIL代码,类型元数据,清单和必需的资源)都包含在一个*.exe 或 *.dll 包中。
多文件程序集是一个.NET *.dll 的集合,这些dll作为单个逻辑单元进行部署和版本化。通常,其中一个会作为主模块,它将包含程序集级别的清单(以及必要的CIL代码,元数据,头信息和可选资源)。主模块的清单记录了它依赖的每一个*.dll文件。根据命名习惯,多文件程序集的辅助模块的文件扩展名一般是 *.netmodule,但这不是强制要求。辅助模块也包含CIL代码和类型元数据,同时还有一个模块级别的清单,它记录该模块外部引用的程序集。
多文件程序集的优点是:提高了程序加载的效率-可按需加载;允许模块由不同的.NET编程语言编写。组成一个多文件程序集的模块并没有相互连接成一个大文件,它们只是依靠在主模块清单中记录的信息逻辑地连接在一起。
4,私有程序集要求放置在客户端应用程序所在目录或其子目录下。我们假定私有程序集并不需要详细检查版本,因为客户端应用程序是唯一知道其存在的实体。.NET运行环境使用一种叫做探测(probing)的技术解析私有程序集的位置。该技术是一种把外部程序集请求映射到被请求的二进制文件的过程。严格来说,一个加载请求可以使显示的或隐式的。隐式的加载请求发生在CLR查询清单的.assembly extern标记来解析程序集位置的时候。显式的加载请求发生在以编程方式调用System.Reflection.Assembly类的Load()或LoadFrom()方法时,这两个方法主要在后期绑定或动态调用类型成员时用到。不管是显式还是隐式,在CLR获得程序集的名称之后,便开始探测客户端应用程序目录(及其子目录)下的*.dll文件,如果找不到就尝试查找具有相同名字的可执行程序集*.exe,如果还找不到就会引发FileNotFound异常。当然我们也可以创建如*.config格式的配置文件来修改探测规则。
5,共享程序集是类型和(可选)资源的集合,它与私有程序集的区别在于共享程序集的一个副本可供一台机器上的多个应用程序使用。共享程序集是安装在GAC下的,GAC是在Windows目录下名为Assembly的目录(如:C:\Windows\Assebly)。程序集被部署到GAC前,都会被赋予一个强名称,该强名称标识该程序集的发行者,其作用有点像COM中的GUID。强名称是基于密码学上的公钥与私钥的,这种机制比GUID更唯一和抗篡改。强类型由一组相关的数据组成:程序集的名称,版本号,公钥值(由sn.exe工具生成),用于本地化的可选区域性标识以及嵌入的数字签名。