代码改变世界

3.9.1 发布者策略管理

2011-11-28 14:06  iRead  阅读(392)  评论(0编辑  收藏  举报

  在上一节的例子中,是有程序集的发布者将程序集的一个新版本发送给管理员,后者安装程序集,并手动编辑应用程序或机器的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="netural"/>
        <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.1.0.JeffTypes.dll

      /version:1.0.0.0

      /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)是现在要生成的发布者策略程序集文件的扩展名。1
  • /version  这个开关标识发布者策略程序集的版本;这个版本号与JeffTypes程序集本身没有任何关系。看得出来,发布者策略程序集本身也有一套版本机制。例如,今天,发布者可以创建一个发布者策略,将JeffTypes的1.0.0.0版本重定向到版本2.0.0.0。将来,发布者可以把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标识的其他目录中。

重要提示:只有在部署程序集的更新版本或Service Pack版本的时候,才能创建一个发布者策略程序集。执行应用程序的全新安装时,不应安装发布者策略程序集。

  关于发布者策略,最后还要注意一点。发布者推出一个发布者策略程序集时,因为某种原因,新的程序集可能引入了比它修复的还要多的bug2。发证这种情况后,管理员可以指示CLR忽略发布者策略程序集。为此,管理员要编辑应用程序的配置文件,并添加以下publisherPolicy元素:

  <publisherPolicy apply="no"/>

  这个元素可以作为应用程序配置文件的<assemblyBinding>元素的一个子元素使用,使其应用于所有程序集;也可作为应用程序配置文件的<dependentAssembly>元素的一个子元素使用,使其应用于一个特定的程序集。这样一来,CLR处理应用程序的配置文件时,就知道自己不应在GAC中检查发布者策略程序集。所以,CLR会继续使用旧版本的程序集。但要主要,CLR仍会检查并应用Machine.config文件中指定的任何策略。

重要提示:提供发布者策略程序集,发布者相当于肯定了一个程序集的不同版本的兼容性。如果新版本的程序集不兼容某个老版本,就不应创建发布者策略程序集。通常,如果需要生成程序集的一个bug修复版本,就应该提供发布者策略程序集。作为发布者,应主动测试新版本程序集的向后兼容性。另一方面,如果要在程序集中增添新功能,就应该把它视为与之前的版本没有关系的一个程序集,不应配套提供一个发布者策略程序集。另外,也不必测试这类程序集的向后兼容性。


  1、现在要生成的是发布者策略程序集,它针对的是一个名为JeffTypes的程序集。这是两个不同的程序集,请注意区分。

  2、参考上一条注释,这里所说的bug是由发布者策略程序集所针对的那个程序集引入的,而不是由发布者策略程序集本身引入的。