首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

11.8  配置共享程序集

和私有程序集一样,共享程序集也可以使用*.config文件进行配置。由于共享程序集安装在一个公共的地方(GAC),因此并不需要像私有程序集那样在配置文件中定义<privatePath>元素(如果客户程序既使用共享程序集又使用私有程序集,那么在配置文件里<privatePath>元素还是有的)。

如果想要指示CLR绑定到某一程序集的其他版本,可以使用应用程序配置文件和共享程序集,我们就可以有效地跳过客户程序清单中记录的值。这样做的好处多多。比如,假设你已经发布了程序集(代码库)的1.0.0.0版本,但是后来发现一个重大的缺陷。一种补救措施是:重新生成客户端应用程序,使其引用已经消除缺陷的程序集版本(如1.1.0.0版本),然后重新把新的客户端应用程序和新的代码库发布到每一台目标机器上。

另一种做法是发布新的代码库,使用一个*.config文件在运行时自动指示运行库绑定到新的无错版。只要新版本的程序集已经安装到GAC中,原来的客户应用程序就不需要重新编译生成和发布。

再举一个例子:在发布了第一个消除缺陷的程序集(1.1.0.0版本)的一到两个月后,一些新的功能被添加到程序集中,由此而产成2.0.0.0版本。显然,目前的客户端应用程序是根据代码库的1.0.0.0版本进行编译的,因此它并不知道新版本程序集里面的新类型(假定在客户端应用程序代码里并没有引用到)。

文本框:  
图11-24  安放好CarLibrary.dll的当前版本


此时,如果客户端应用程序想要使用2.0.0.0版本里面提供的新功能,在.NETF,可以把2.0.0.0版本的程序集发布到目标机器,让2.0.0.0版本和1.0.0.0版本和平共处。所以在需要的时候,只要修改应用程序的配置文件,然后原有的客户程序就可以动态地定向到2.0.0.0版本了(以便调用新的功能),这一切并不需要重新编译和部署。

11.8.1  冻结当前的共享程序集

为了说明如何动态绑定到共享程序集的某一个版本,请打开Windows资源管理器,然后把CarLibrary.dll当前版本(1.0.0.0)放到独立的目录(Version 1)中,如图11-24所示。

11.8.2  构建共享程序集2.0.0.0版本

现在让我们来更新CarLibrary项目的内容。定义一个枚举类型MusicMedia,定义四种音乐播放器:

 

// 表示各种音乐播放器的集合。

public enum MusicMedia

{

  musicCd,

  musicTape,

  musicRadio,

  musicMp3

}

 

接着,为Car类型添加一个新的公共方法,允许调用者打开某一个给定的音乐播放器。

 

public abstract class Car

{

...

  public void TurnOnRadio(bool musicOn, MusicMedia mm)

  {

    if(musicOn)

      MessageBox.Show(string.Format("Jamming {0}", mm));

    else

      MessageBox.Show("Quiet time...");

  }

...

}

 

更新Car类的构造函数,其中使用一个MessageBox验证我们正在使用CarLibrary 2.0.0.0版本:

 

public abstract class Car

{

...

  public Car()

  {

    MessageBox.Show("Car 2.0.0.0");

  }

  public Car(string name, short max, short curr)

  {

    MessageBox.Show("Car 2.0.0.0");

    petName = name; maxSpeed = max; currSpeed = curr;

  }

...

}

 

最后,在重新编译前,请确保程序集的版本号是2.0.0.0,修改[AssemblyVersion]特性的值:

 

// CarLibrary 版本2.0.0.0(现在是有音乐的!)。

[assembly: AssemblyVersion("2.0.0.0")]

 

现在查看项目的\Bin\Debug目录,会发现新版本的程序集(2.0.0.0)。而1.0.0.0版本则还在Version 1子目录下。把新版本安装到GAC中,那么同一程序集的两个版本都被安装在GAC中,如图11-25所示。

如果现在使用Windows资源管理器执行SharedCarLibClient.exe,还能看到显示“Car 2.0.0.0”的MessageBox,因为现在客户程序还是引用版本1.0.0.0程序集。我们应该如何指示CLR去绑定版本2.0.0.0呢?

11-25  和平共处的两个版本

11.8.3  动态重定向到共享程序集的特定版本

如果想要CLR加载一个不同于程序清单中的共享程序集版本,需要使用*.config配置文件中的<dependentAssembly>元素。在<dependentAssembly>元素里,需要创建<assemblyIdentity>子元素,它用于指定列在客户清单中的程序集的友好名称(CarLibrary)和一个可选的区域性(culture)特性(如果想使用机器的默认区域性设置,则把该特性设置为空或者完全省略就可以了)。另外<dependentAssembly>元素下还需要创建<bindingRedirect>子元素,它用来定义程序清单当前指向的版本(使用子元素的oldVersion特性表示)和GAC中的替代版本(使用子元素的newVersion特性表示)。

SharedCarLibClient应用程序目录下创建一个新的名为SharedCarLibClient.exe.config的配置文件(文件具体内容如下)。当然,你的publicKeyToken特性的值应该会与下面代码中的不同。它的具体值可以通过使用ildasm.exe查看客户程序清单获得,或者直接到GAC中查看。

 

<configuration>  

  <runtime>

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <dependentAssembly>

       <assemblyIdentity name="CarLibrary"

           publicKeyToken="219ef380c9348a38"

           culture="neutral"/>

       <bindingRedirect oldVersion= "1.0.0.0"

         newVersion= "2.0.0.0"/>

      </dependentAssembly>

    </assemblyBinding>

  </runtime>

</configuration> 

 

现在运行SharedCarLibClient.exe。程序将会弹出MessageBox显示2.0.0.0被加载的信息(注意前面更新了的构造函数实现)。如果把newVersion特性设置为1.0.0.0(或者直接把*.config文件删除),将会看到1.0.0.0版本被加载,因为CLR在程序清单中找到1.0.0.0的记录。

程序配置文件中可以定义多个<dependentAssembly>元素。假定SharedCarLibClient.exe原来引用了MathLibrary程序集的2.5.0.0版本,而现在需要重定向到MathLibrary3.0.0.0版本(同时CarLibrary重定向到2.0.0.0版本),则SharedCarLibClient.exe.config文件内容如下:

 

<configuration>  

  <runtime>

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <dependentAssembly>

       <assemblyIdentity name="CarLibrary"

           publicKeyToken="219ef380c9348a38"

           culture=""/>

       <bindingRedirect oldVersion= "1.0.0.0"

         newVersion= "2.0.0.0"/>

      </dependentAssembly>

      <dependentAssembly>

       <assemblyIdentity name="MathLibrary"

           publicKeyToken="219ef380c9348a38"

           culture=""/>

       <bindingRedirect oldVersion= "2.5.0.0"

         newVersion= "3.0.0.0"/>

      </dependentAssembly>

    </assemblyBinding>

  </runtime>

</configuration> 

11.8.4  再次研究.NET Framework 2.0 配置工具

正如你所希望的,使用.NET Framework图形界面的配置工具可以生成以共享程序集为中心的*.conifg文件。和生成私有程序集的*.conifg配置文件过程一样,我们首先引入需要配置的*.exe程序,为了看到效果,请把刚才编写的SharedCarLibClient.exe.config文件删除。然后用鼠标右击配置工具的Applications节点添加SharedCarLibClient.exe。接下来,单击“+”图标展开刚才新添加的节点,选择其中的Configured Assemblies子节点,然后在右侧窗口内单击Configure an Assembly

此时,出现的对话框允许我们在非常友好的界面中建立<dependentAssembly>元素。首先,选择“Choose an assembly from the list of assemblies this application uses”单选按钮(它提供的功能其实就是把该程序集清单的内容展示给你看),按下Choose Assembly按钮。

一个对话框会立即弹出,它不仅把在程序清单中列出的程序集显示出来,而且还会把列出程序集自身引用的相关程序集也显示出来。在本例子中,请选择CarLibrary。当选择完毕并按下Finish按钮后,会弹出一个属性页。在里面的Binding Policy选项卡里可以生成<dependentAssembly>子元素。

Binding Policy选项卡里,首先在Requested Version文本框中设置oldVersion特性(1.0.0.0)的值,然后在New Version文本框中设置newVersion特性的值(2.0.0.0)。这些完成后,如下配置文件将被生成:

 

<?xml version="1.0"?>

<configuration>

  <runtime>

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <dependentAssembly>

       <assemblyIdentity name="CarLibrary"

         publicKeyToken="219ef380c9348a38" />

       <publisherPolicy apply="yes" />

       <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />

      </dependentAssembly>

    </assemblyBinding>

  </runtime>

</configuration>

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论