读经典——《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 文件中指定的任何策略。

读经典——《CLR via C#》(Jeffrey Richter著) 笔记_发布者策略控制的更多相关文章

  1. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_高级管理控制(配置)

    一个应用程序的XML配置文件示例: <?xml version="1.0"?> <configuration> <runtime> <as ...

  2. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_通过ILDasm.exe查看编译器如何将类型及其成员编译成元数据

    [实例代码] using System; public sealed class SomeType //-------------1 { //嵌套类 private class SomeNestedT ...

  3. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(二)

    [基元类型推荐] 推荐直接使用 FCL 类型. [理由] 编码时不至于困惑string与String的使用.由于C#的stirng(一个关键字)直接映射到System.String(一个 FCL 类型 ...

  4. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(一)

    [概念] 编译器直接支持的数据类型 [C#基元类型与对应的 FCL 类型] C#基元类型 FCL 类型 说明 sbyte System.Sbyte 有符号8位值 byte System.Byte 无符 ...

  5. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_运行时解析类型引用

    public sealed class Program{ public static void Main() { System.Console.WriteLine("Hi"); } ...

  6. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_方法执行

    [前言] 方法执行前,CLR 会检测方法内代码引用的所有类型.同时 CLR 会分配一个内部数据结构,用来管理对所有引用的类型的访问. 首次执行方法时,托管程序集会把 IL 转换成本地 CPU 指令,并 ...

  7. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_元数据

    1.元数据简介 全称:metadata 属性:数据表集合 产地:面向 CLR 的编译器在托管模块中生成 2.元数据内部结构及与托管模块的关系 [概述] 托管模块中包含着元数据,元数据是由一组数据表组成 ...

  8. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_友元程序集

    [应用场景] 程序集A访问程序集B定义的Internal访问类型的类的成员. [使用方式] 在构建程序集B的时候,引入System.Runtime.CompilerServices,以此来添加Inte ...

  9. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_类型的各种成员

    [Class中,可能包含的成员] 常量, 字段, 实例构造器, 类型构造器, 方法, 操作符重载, 转换操作符, 属性, 事件, 类型(Class)

随机推荐

  1. js中的操作符

    写在前面 js语法 DOM对象(把body,div,p等节点树看成一个对象) BOM对象(把浏览器的地址栏历史记录DOM等装在一个对象) 浏览器是宿主,但js的宿主不限于浏览器,也可以是服务器,如no ...

  2. php判断终端是手机还是电脑访问网站代码

    ?php function check_wap() { if (isset($_SERVER['HTTP_VIA'])) return true; if (isset($_SERVER['HTTP_X ...

  3. git push是报Permission denied (publickey)错误解决

    今天晕了半天了,搞了个git工程到github上,以为很简单,因为之前也弄过,那知道搞了大半天都搞不好,一直报如下错误 D:\javawork\ee-0.0.1-SNAPSHOT>git pus ...

  4. Java-马士兵设计模式学习笔记-工厂模式-模拟Spring读取Properties文件

    一.目标:读取properties文件,获得类名来生成对象 二.类 1.Movable.java public interface Movable { void run(); } 2.Car.java ...

  5. 20.LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别

    转载:https://www.cnblogs.com/panfeng412/archive/2011/10/20/library_path-and-ld_library_path.html LIBRA ...

  6. Luogu 3402 可持久化并查集

    点开这题纯属无聊……不过既然写掉了,那就丢一个模板好了 不得不说,可持久化并查集实现真的很暴力,就是把并查集的数组弄一个主席树可持久化. 有一点要注意的是不能写路径压缩,这样跳版本的时候会错,所以弄一 ...

  7. Python字典内置方法

    Python字典包含了以下内置方法: 序号 函数及描述 1 radiansdict.clear()删除字典内所有元素 2 radiansdict.copy()返回一个字典的浅复制 3 radiansd ...

  8. Entity Framework Tutorial Basics(38):Explicit Loading

    Explicit Loading with DBContext Even with lazy loading disabled, it is still possible to lazily load ...

  9. 函数的返回值是如何带出和接收的以及内存中的活动情况.RP

    函数返回值时,要生成一个值的副本. 而用引用返回值时,不生成值的副本. 例如,下面的程序是有关引用返回的4种形式: //********************* //** ch9_6.cpp ** ...

  10. 多线程学习-基础(七)sleep()和wait()的区别

    一.sleep()和wait()的区别共同点:1.他们都是在多线程的环境下,都可以在程序的调用出阻塞指定的毫秒,然后继续往后执行(在当前线程再次拿到cpu的执行权之后).2.wait()和sleep( ...