The wind call my name

用知识和思考来丈量世界
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

《Programming .Net Components》学习笔记(十)

Posted on 2007-06-02 09:49  徐鸿翼  阅读(559)  评论(0编辑  收藏  举报

作为组件技术必须提供版本控制的支持,用来确保客户端应用程序有一种明确的方法与服务端组件的可兼容版本互动。对于你选择的组件共享模式来说,组件版本是一种挑战。私有组件(应用程序内部使用的本地私有组件)会很少暴露版本问题,因为它与应用程序是绑定的——除非显式介入和导致不兼容。另一方面,共享组件会导致大量版本问题,因为它们存储全局已知位置并且被多个应用程序使用。虽然如此,一个成熟的组件技术必须允许多应用程序来共享服务端组件,还应允许不同的客户端应用程序使用不同版本的服务端组件。在全局位置部署DLLs(如系统目录),如果在过去这样做会是致命的,会导致一个恶魔般的选择——要么扼杀更改,要么卷入DLL地狱。所以也不必奇怪,.NET平台为什么会把简化组件部署和版本控制最为一个主要目标。

程序集版本号

一、 程序集版本号

每个程序集都有一个应用于程序集中所有组件上的版本号。在Visual Studio 2005项目设置中可以指定版本号,也可以在链接阶段中,通过命令提示符程序和MSBuild来赋值版本号。 Visual Studio 2005每个项目的程序集属性存储在AssemblyInfo.cs文件中,例如程序级版本信息:

[assembly: AssemblyVersion("1.0.0.0")]

版本号会被载入到服务端的程序集清单中。当客户端开发者添加一个服务端的程序集引用时,客户端程序集会通过其清单来获取已编译服务端程序集的正确版本。如果客户端使用来源于程序集MyAssembly的1.2.3.4版本中的MyClass类,那么客户端程序集清单中会记录请求MyAssembly的1.2.3.4版本进行操作而且会包含这样的生明:

.assembly extern MyAssembly

{

   .ver 1:2:3:4

}

在运行时,.NET会解析请求程序集的位置,并确保获得一个可兼容的程序集。如果未发现可兼容的程序集则会抛出一个异常。那么什么才能构成可兼容的程序集呢?可兼容性的规则如下:对于一个强命名程序集来说,可兼容程序集定义是必须与客户端程序集清单中的请求版本相一致;对于友好命名程序集来说,任何具有同样友好命名的程序集都认为是可兼容的。

二、 版本号元素

版本号由四个号码组成,依次是:主版本号,次版本号,生成版本号和修订版本号。虽然可以对这些号码指定任意的语义,但为了传达给程序集消费者版本变化的意义,就需要遵守这样的约定:一个好的生成版本号应指示出同一可兼容程序集的新版本,一个好的修订版本号应指示出一些小变化或因本地化而作成的改变。作为产品发布的一部分,应当检查是否已相应地递增了版本号部分,来反映新发行版本的性质。

三、 提供版本号

对于一个新程序集,Visual Studio 2005提供的默认版本号是1.0.0.0。但是也可以显式的指定版本号,或让Visual Studio自动生成。如果指定生成版本号和修订版本号为“*”或者是空白,那么自动生成时,编译器会使用自2000年1月1日到现在的天数作为生成版本号,使用自午夜时分到现在时刻的秒数除以2作为修订版本号,且都以本地时间为准。

 

程序集部署模型

.NET提供了两种程序集部署模型:私有的和共享的。使用私有程序集,每个客户端应用程序都维护一个该程序集的私有本地副本。部署私有程序集,只需复制到使用它的应用程序目录即可。虽然客户端应用程序会在安装期间通过复制的方式来部署所以请求的私有程序集,但并没有阻止在以后来添加一个新的私有程序集。这样就允许对于客户端和服务端的不同生命周期进行相互分离。当复制一个私有程序集的新版本到应用程序目录时,因为一个文件夹不能包含相同文件名的多个文件,新副本会覆改旧副本。私有程序集通常是后置可兼容的,因为他必须支持上一个版本支持的所有功能上的可用性,否则当旧版本的客户端应用程序在试图新版本服务端程序集时就会跳出。

共享程序集是一个可以被多个客户端应用程序同时使用的程序集。所以必须在一个全局已知位置安装共享程序集,这个位置被称为“global assembly cache(全局程序集缓存GAC)”。GAC可支持共享程序集的多个版本,也能同时执行程序集的多个版本。这就意味着如果仍旧存在一个较老版本,共享程序集就不再需要在向后兼容了。共享程序集可简化复杂的部署状况,除非是对于构架或第三方组件提供商,因为当一个新版本的程序集被安装到GAC中时,它会立即对于该计算机上的所以客户端应用程序可见。

负责管理程序集兼容性和确保客户端应用程序得到可兼容的程序集的.NET实体被称为“assembly resolver(程序集解析器)”。当客户端应用程序声明一个类型而拥有该类型的程序集尚未加载时,.NET会在客户端程序集清单中寻找客户端认为正确的程序集名称和版本,随后会传递信息到程序集解析器。而程序集解析器总是试图提供给客户端一个可兼容版本的服务端程序集。所以,程序集解析器会首先在GAC中寻找,如果找到就会加载它。如果在GAC未找到可兼容的程序集,解析器就会在客户端应用程序文件夹中寻找。如果客户端应用程序文件夹中存在请求程序集的可兼容的私有版本,解析器就会加载使用该版本。如果没有匹配的私有程序集被发现,那么就会抛出一个异常。默认情况下,.NET不允许客户端应用程序与不可兼容程序集互动。

避免混淆和匹配私有和共享程序集(指同一程序集的不同版本,有的是私有的,有的是共享的)。这会因为难以辨认和解析较老版本和较新版本,而导致冲突。

 

根据原版英文翻译,所以不足和错误之处请大家不吝指正,谢谢:)