在 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_高级管理控制(配置)中,是由程序集的发布者将程序集的一个新版本发送给管理员,后者安装程序集,并手动编辑应用程序后机器的 XML 配置文件。通常,发布者希望在修复了程序集的一个 bug 后,能采取一种容易的方式将新的程序集打包并分发给所有的用户。但是,发布者还需要一种方式告诉每个用户的 CLR 使用新的程序集版本,而不要继续使用旧版本。当然,可以指示每个用户手动修改应用程序或机器的 XML 配置文件,但这相当不方便,而且容易出错。因此,发布者需要使用一种方式来创建策略信息,当新程序集安装到用户机器上时,就会安装这些策略信息。本节将描述程序集的发布者如何创建这种策略信息。
假定你是一个程序集的发布者,而且刚刚创建了程序集的一个新版本,并修复了几个 bug。打包要发送给所有用户的新程序集时,应同时创建一个 XML 配置文件。 这个配置文件和以前讨论过的配置文件差不多。下面是一个用户 JeffTypes.dll 程序集的示例文件(名未JeffTypes.config):
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="JeffTypes" publicKeyToken="32ab4ba45e0a69a1" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
<codeBase version="2.0.0.0" href="http://www.Wintellect.com/JeffTypes.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
当然,发布者只能为自己创建的程序集设置策略。除此之外,前面展示的是在发布者策略配置文件中唯一能使用的元素:例如:probing 或 publisherPolicy 元素是不能使用的。这个配置文件指示 CLR 一旦发现对 JeffTypes 程序集的 1.0.0.0 版本的引用,就自动加载 2.0.0.0 版本。现在,作为发布者,可创建包含这个发布者策略配置文件的一个程序集。为了创建发布者策略程序集,要像下面这样运行 AL.exe:
AL.exe /out:Policy...JeffTypes.dll
/version:...
/keyfile:MyCompany.snk
/linkresource:JeffTypes.config
下面是对 AL.exe命令行开关的解释:
- /out 这个开关指示 AL.exe 创建一个新的 PE 文件,本例就是 Policy.1.0.JeffTypes.dll,其中除了一个清单之外什么都没有。程序集的名称很重要。名称的第一个部分(Policy)告诉 CLR 该程序集包含发布者策略信息。第二部分和第三部分(1.0)告诉 CLR 这个发布者策略程序集适用于 major 和 minor 版本为 1.0 的任何版本的JeffTypes 程序集。发布者策略只能和程序集的major 和 minor 版本号关联:不能喝 build 或 revision 号关联。名称的第四部分(JeffTypes)指出与这个发布者策略对应的程序集的名称。名称的第五部分(dll)是现在要生成的发布者策略程序集文件的扩展名。
- /version 这个开关标识发布者策略程序集的版本:这个版本号与 JeffTypes 程序集本身没有任何关系。看得出来,发布者策略程序集本身也有一套版本机制。例如,今天,发布者可以创建一个发布者策略,将 JeffTypes 的 1.0.0.0 重定向到版本 2.5.0.0。CLR根据/version 开关指定的版本号来选择最新版本的发布者策略程序集。
- /keyfile 这个开关指示 AL.exe 使用发布者的 “公钥/私钥对” 对发布者策略程序集进行签名。这个密钥对还必须匹配于所有版本的 JeffTypes 程序集的密钥对。毕竟,只有这样, CLR 才知道 JeffTypes 程序集和发布者策略文件是由同一个发布者创建的。
- /linkresource 这个开关告诉AL.exe 将 XML配置文件作为一个资源链接(而非嵌入)到程序集。最后的程序集是由两个文件构成的(现在要生成的 Policy.1.0.JeffTypes.dll 和 刚才已经创建好的 XML 配置文件 JeffTypes.config),两个文件都必须随同新版本的JeffTypes 程序集打包并部署到用户机器上。顺便说一句,不能使用 AL.exe 的 /embedresource 开关将 XML 配置文件嵌入程序集文件,从而获取一个单文件的程序集。这个因为 CLR 要求 XML 文件包含在它自己的一个单独的文件中。
一旦生成这个发布者策略程序集,就可随同新的 JeffTypes.dll 程序集文件打包并部署到用户机器上。发布者策略程序集必须安装到GAC中。虽然 JeffTypes 程序集也能安装到 GAC 中,但并不是必须的——它可以部署到应用程序的基目录,后者部署到由一个 codeBase URL标识的其他目录中。
关于发布者策略,最后还要注意一点。发布者推出一个发布者策略程序集时,因为某种原因,新的程序集引入的 Bug 可能比它修复的 Bug 还要多。发生这种情况后,管理员可以指示 CLR 忽略发布者策略程序集。为此,管理员要编辑应用程序的配置文件,并添加以下 publisherPolicy 元素:
<publisherPolicy apply="no" />
这个元素可以作为应用程序配置文件的<assemblyBinding> 元素的一个子元素使用,使其应用于所有程序集;也可作为应用程序集配置文件的<dependentAssembly> 元素的一个子元素使用,使其应用于一个特定的程序集。这样一来,CLR 处理应用程序的配置文件时,就知道自己不应再 GAC 中检查发布者策略程序集。所以,CLR会继续使用旧版本的程序集。但要注意,CLR 仍会检查并应用 Machine.config 文件中指定的任何策略。