利用.net框架简化发布和解决dll hell问题(5)
通常,应用程序编写者不对应用程序使用的共享汇编有同等程度的控制。结果,在每次引用共享汇编时都检查版本信息。另外,.net 框架允许应用程序和管理员通过指定版本策略重载应用程序使用的共享汇编版本。
共享汇编通常部署到全局汇编库。全局汇编库是供多个应用程序使用的机器范围的汇编库。使用该库不是必要条件,但这样做有很多好处。例如,自动提供多个版本的汇编并行存储。而且,管理员能使用该库部署他们需要的每个机器上的应用程序要使用的缺陷修复或安全补丁。在该方案中,配置汇编到全局汇编存储能影响机器上的多个应用程序。.net 框架利用版本政策(稍候描述)的概念解决了现在出现在系统中共享区域的问题,例如 %windir%\system32。
在库中添加汇编需要明确的管理员操作—实际上,安装过程必须有“管理员权限”。汇编从不在存储结束作为运行一个应用程序的侧面影响,也不是当前工作的共享汇编的任何存储。在 visual studo .net 时间框架中,windows 安装程序将更新为理解汇编和汇编库。这意味着可以使用 windows 安装程序的所有功能,例如使用 .net 应用程序选择安装和应用程序恢复。
.net sdk 包括两个用于汇编库的工具。第一个是称为 al 的工具,它允许在库中添加汇编。al 使开发和测试方案变得方便,它不需要创建整个 windows 安装程序包在库中添加一个汇编。使用 /install 开关在库中添加汇编:
al /install:myassembly.dll
第二个工具是 windows shell extension,它允许您使用 windows explorer 操作库。图 4 表示全局汇编库的视图。
<img src="/files/bpic/2006-10/7/0610717102915402.gif"">
图 4. 全局汇编库
共享名
共享名用于使严格的命名需求与共享汇编结合起来。共享名有三个目标:
名称唯一:共享汇编必须具有全局唯一的名称。
防止名称冒充:作为开发人员,不希望有人发布您的汇编的后继版本并假称它是您发布的,无论是意外还是故意的。
提供引用标识:当涉及引用一个汇编时,共享名用于保证载入的汇编来自所期望的发行者。
共享名使用公共密钥加密实现。通常,过程如下所示:汇编的编写者产生一对密钥(或使用已有的),标记包含专有密钥清单的文件,并给调用者提供公共密钥。当引用汇编时,调用者记录生成强名称专有密钥相应的公共密钥。图 5 略述了该过程在开发期间如何工作,包括密钥如何存储在元数据中及如何生成签名。
该方案是称为“main”的汇编,它引用一个称为“mylib”的汇编。mylib 具有共享名。重要的步骤如下所述。
<img src="/files/bpic/2006-10/7/0610717102943168.gif"">
图 5. 实现共享名的过程
开发者调用在密钥对中传递的编译器和一组汇编的源文件。密钥对通常由称为 sn 的 sdk 工具生成的。例如,下面的命令生成一个新的密钥对并保存的文件中:
sn 杒 mykey.snk
多数的编译器将汇编作为编辑步骤的一部分。下面是一个 c# 命令的例子,它接受密钥对并给汇编签名:
csc /t:library math.cs /a.keyfile:mykey.snk /a.version:1.0.0.0
当编译器生成汇编时,公共密钥作为汇编标识的一部分保存在清单中。包括公共密钥作为标识的一部分给汇编提供了全局唯一的名称。
汇编生成后,包含清单的文件由专有密钥标记。结果签名保存在文件中。
当编译器生成 main 汇编时,mylib 汇编的公共密钥就作为引用 mylib 的一部分保存在 main 的清单中。
在运行时,.net 框架中有两个步骤保证共享名给予开发人员所需的利益。首先,在汇编安装到全局汇编库时,验证 mylib 的共享名签名。(没有配置到库中的验证签名的选项也是可用的。)验证签名保证 mylib 的内容从汇编建立以来没有改变。第二步是验证作为 main 引用 mylib 的一部分保存的公共密钥与 mylib 身份的一部分的公共密钥相匹配。如果这些密钥相同,main 的作者就能保证载入的 mylib 版本来自同一个的发布者,该发布者编写了建立 main 的 mylib 版本。当涉及 main 引用 mylib 时,该密钥等效检查在运行时完成。