11.10 发行者策略程序集
下一个关于配置的话题是发行者策略程序集(Publisher Policy Assembly)的作用。我们已经知道,使用*.config文件可以忽略清单中记录的版本,并使客户端程序绑定到指定版本的共享程序集。这一切看上去都非常美好,但请想象一下,一个管理员需要做的工作是:重新配置所有的客户端程序,使其绑定到CarLibrary.dll程序集的2.0.0.0版本。由于配置文件的命名要求非常严格,因此需要把相同的XML内容复制到所有的客户端(而能够这样做,还需要知道所有使用CarLibrary程序集的客户端目录位置)。很明显,这是一场噩梦。
发行者策略允许程序集的发行者(用户、用户的部门、用户的公司等)在安装相关的最新版本程序集到GAC的同时,把一个*.config文件的二进制版本(作为程序集看待,发行者策略程序集)也安装到GAC。这样做的好处是客户端应用程序目录不需要包含任何*.config文件。CLR会读取当前客户端程序的清单,尝试在GAC中查找被请求的版本。但如果CLR找到一个发行者策略程序集,它会读取其中嵌入的XML数据,在GAC级别执行请求重定向(前面的做法是在客户端程序级别进行重定向)。
我们使用.NET的al.exe(assembly linker)工具在命令行创建发行者策略程序集。尽管该工具拥有众多选项,但创建一个发行者策略程序集只需要使用到以下几个:
l 含有重定向指令*.config或者*.xml文件的位置。
l 生成的发行者策略程序集的名称。
l 用于对发行者策略程序集签名的*.snk文件的位置。
l 创建的发行者策略程序集的版本号。
以下命令就是创建控制CarLibrary.dll的发行者策略程序集:
al /link: CarLibraryPolicy.xml /out:policy.1.0.CarLibrary.dll
/keyf:C:\MyKey\myKey.snk /v:1.0.0.0
这里,XML内容被包含在CarLibraryPolicy.xml文件中。命令输出的文件名(格式必须为:policy.<major>.<minor>.assemblyToConfigure)由/out标志指定。另外包含公钥私钥对的文件名由/keyf选项指定(记住,因为发行者策略文件是共享的,因此它必须具有强名称)。
命令执行完以后,一个新的程序集可以被安装到GAC中,它将强制要求所有客户端程序绑定到CarLibrary.dll的2.0.0.0版本,而不需要使用应用程序配置文件。
禁止发行者策略
现在,假定你(作为系统管理员)需要部署一个发行者策略程序集(和最新版本的相关程序集)到一台客户端机器上。如果比较幸运的话,90%的受影响的客户端应用程序会正确地重绑定到2.0.0.0版本。先不管原因,假定剩下的10%的客户程序在使用CarLibrary.dll 2.0.0.0版本时发生了错误(我们知道,向后兼容的软件并不是总能100%地正常工作)。
在这种情况下,针对每个有问题的客户端应用程序创建一个配置文件,通过该文件通知CLR忽略安装在GAC上的发行者策略程序集,这是完全可以的。那些其余的能够正常工作的客户端程序则接受发行者策略程序集指定的重定向,它们使用最新版本的程序集。为了逐个客户端程序地禁止发行者策略,我们需要创建一个使用<publisherPolicy>元素的*.config文件(根据客户端应用程序名称命名的。前面讲过,因为使用了发行者策略程序集,所以客户端程序目录原来并没有配置文件),同时把该元素的apply特性设置为no。现在,CLR将会加载客户端程序清单中原来指定的程序集版本。
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<publisherPolicy apply="no" />
</assemblyBinding>
</runtime>
</configuration>






