用强名称程序集避免“DLL地狱”

ZDNet软件频道 时间:2003-07-08 作者:ZDNet China |  我要评论()
本文关键词:
为Microsoft .NET框架创建应用程序时,你获得的最大的一个承诺就是能避免所谓的DLL地狱。为了理解这个承诺,开发者需要熟悉“强名称”(Strong Names)的概念与实现。本文将引导你理解强名称在托管代码中的应用。
本文译自Builder.com,未经许可请勿转载为Microsoft .NET框架创建应用程序时,你获得的最大的一个承诺就是能避免所谓的DLL地狱。它是指当一个组件更新后,可能会中断依赖于它的其他应用程序。然而,为了理解这个承诺,开发者需要熟悉“强名称”(Strong Names)的概念与实现。本文将引导你理解强名称在托管代码中的应用。

为什么要使用强名称

在讨论强名称的好处之前,先来看看它的定义。强名称由用于标识一个程序集的信息构成,其中包括程序集的文本名称、分为4部分的版本号、区域性信息(如果有的话)、一个公钥以及一个数字签名。这些信息存储在程序集的清单(manifest)中。清单包含了程序集的元数据,并嵌入程序集的某个文件中。


注意
大多数程序集(比如使用Visual Studio .NET创建的那些)都是单文件程序集,也就是只有一个.exe或者.dll文件。在这种情况下,清单直接嵌入单文件程序集中。但是,你可用“程序集生成工具”(Al.exe)来创建多文件程序集。



在程序集中包括一个强名称后,公共语言运行库(CLR)可保证具有相同强名称的两个程序集在任何方面都是完全一致的。换言之,强名称为CLR提供了一个程序集的惟一性标识。除此之外,添加一个强名称还可确保二进制完整性,因为CLR可在程序集加载时执行验证,判断它自从编译以来是否被篡改过。

在两种主要的情况下,开发者应为一个程序集包括强名称:

  • 共享程序集。通过包括强名称,程序集在安装到“全局程序集缓存”(GAC)之后,就由同一台机器上运行的多个应用程序共享。这种代码共享模型与非托管世界中使用的模型刚好相反。在非托管世界中,COM组件一旦编译并在系统注册表中注册,就自动共享。
  • Serviced Component。一个.NET类要想使用企业服务(COM+服务),比如分布式事务处理和对象池等等,那么包含类(称为Serviced Component,因为它从EnterpriseServices.ServicedComponent类继承)的程序集必须有一个强名称。有了强名称后,企业服务才能保证加载正确的程序集。企业服务(DLLHost.exe)容纳的进程中所运行的Serviced Component应放到GAC中;相反,作为库应用程序在调用者的进程中运行的那些ServicedComponent则不必这样做。

在第一种情况下(共享程序集放到GAC中),主要的优点包括:

单一部署
由于同一台机器上的所有应用程序都从GAC加载共享程序集,所以不需要为每个应用程序都部署程序集。这有别于.NET框架默认的“私有程序集”,它必须随同每个应用程序来部署。

绕过验证
如前所述,强名称允许CLR的类加载器验证程序集自编译后便没有被篡改过。将程序集放到GAC中,只有在程序集首次放入GAC时才会执行验证,而不是应用程序每次加载它时都执行验证,这有助于提升性能。

减少工作量
如果多个应用程序引用同一个共享程序集,所有应用程序都从相同的位置加载程序集。因此,操作系统在所有应用程序中共享程序集的代码页,这减少了内存占用。

集中更新
程序集部署到GAC后,就可集中部署修正内容。虽然应用程序默认使用程序当初编译时的版本,而且GAC允许相同程序集的多个版本并存,但只需在machine.config文件中添加一个版本策略,即可强迫机器上的所有应用程序使用新版本,而不是使用旧版本。除此之外,一旦程序集包含强名称,其他代码就可指定:只有来自具有特定强名称的一个程序集中的代码才能调用自己。例如,为一个类添加StrongNameIdentityPermissionAttribute后,就可确保只有具有指定强名称的调用者才能创建这个类的实例,如清单A所示。这个例子指定了PublicKey属性,所以凡是使用与这个公钥配对的私钥签署的任何程序集,都允许实例化Products类。


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134