代码改变世界

3.9 高级管理控制(配置)

2011-11-28 11:43  iRead  阅读(326)  评论(0编辑  收藏  举报

  2.8节“简单管理控制(配置)”简要讨论了管理员如何影响“CLR搜索和绑定程序集的方式”。在那一节中,我们演示了如何将引用的一个程序集的文件移动到应用程序基目录的一个子目录中,以及CLR如何通过应用程序的XML配置文件来定位移动的文件。

  第2章只讨论了probling元素的privatePath属性,本节准备讨论其他XML配置文件元素。以下是一个XML配置文件示例:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="AuxFiles;bin\subdir"/>
      <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>
      <dependentAssembly>
        <assemblyIdentity name="TypeLib" publicKeyToken="1f2e74e897abbcfe" culture="neutral"/>
        <bindingRedirect oldVersion="3.0.0.0-3.5.0.0" newVersion="4.0.0.0"/>
        <publisherPolicy apply="no"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

  这个XML文件为CLR提供了丰富的信息。其中包括:

  • probing元素  查找一个弱命名程序集时,检查应用程序基目录的AuxFiles和bin\subdir子目录。对于强命名程序集,CLR会检查GAC或者codeBase元素指定的URL。只有在未指定codeBase元素的前提下,CLR才会在应用程序的私有路径中检查强命名程序集。
  • 第一个dependentAssembly,assemlyIdentity和bindingRedirect元素  查找由控制着公钥标记32ab4ba45e0a69a1的那个组织发布的、语言文化中性的JeffTypes程序集的1.0.0.0版本时,改为定位同一个程序集的2.0.0.0版本。
  • codeBase元素  查找由控制着公钥标记32ab4ba45e0a69a1的组织发布的、语言文化为中性的JeffTypes程序集的2.0.0.0版本时,尝试在以下URL处发现它:http://www.Wintellect.com/JeffTypes.dll。虽然第2章没有特别指出,但codeBase元素也能用于弱命名程序集。在这种情况下,程序集的版本号会被忽略,而且根本就不应该在XML codeBase元素中写这个版本号。此外,codeBase所定义的URL必须引用应用程序基目录下的一个子目录。
  • 第2个dependentAssembly,assemblyIdentity和bindingRedirect元素  查找由控制着公钥标记1f2e74e897abbcfe的那个组织发布的、语言文化中性的TypeLib程序集的3.0.0.0到3.5.0.0版本时(包括3.0.0.0和3.5.0.0在内),改为定位同一个程序集的4.0.0.0版本。
  • publisherPolicy元素  如果生成TypeLib程序集的组织部署了一个发布者策略文件(详情在下一节讲述),CLR应该忽略该文件。

  编译一个方法时,CLR会确定它引用了哪些类型和成员。根据这些信息,“运行时”检查发出引用的那个程序集的AssemblyRef表,判断该程序集在生成时引用了哪些程序集。然后,CLR在应用程序配置文件中查找程序集/版本,并进行设定的任何版本号重定向操作。接着,CLR查找新的、重定向的程序集/版本。

  如果publisherPolicy元素的apply attribute设为yes,或者该元素被省略,CLR会在GAC中检查新的程序集/版本,并进行程序集发布者认为有必要进行的任何版本号重定向操作。随后,CLR会查找新的、重定向的程序集/版本。(下一节将更详细讨论发布者策略。)最后,CLR在机器的Machine.config文件中检查新的程序集/版本,并进行设定的任何版本号重定向操作。

  到此为止,CLR已经知道了它应该加载的程序集的版本,并尝试从GAC中加载该程序集。如果程序集不在GAC中,而且没有codeBase元素,CLR会像第2章描述的那样探测程序集。如果执行最后一次重定向操作的配置文件同时包含一个codeBase元素,CLR会尝试从codeBase元素指定的URL处加载程序集。

  利用这些配置文件,管理员可以实际地控制CLR加载的程序集。如果一个应用程序出现bug,管理员可以和有问题的程序集的发布者取得联系。发布者可以将一个新的程序集发送给管理员,让管理员安装。CLR默认不会加载这个新的程序集,因为已经生成的程序集没有引用新版本。不过,管理员可以修改应用程序的XML配置文件,指示CLR加载新的程序集。

  如果管理员希望机器上所有应用程序都使用新的程序集,可以修改机器的Machine.config文件(而不是修改应用程序的配置文件)。每当一个应用程序引用新的程序集时,CLR都会自动加载新的程序集。

  如果发现新的程序集没有修复原来的bug,管理员可以从配置文件中删除bindingRedirect设置,应用程序会恢复如初。说了这么一大堆,其实重点只有一个:系统允许使用和元数据记录的不完全匹配的一个程序集版本。这种额外的灵活性是非常有用的。