远程处理中的版本信息
本主题介绍一项传统技术,保留该技术是为了向后兼容现有的应用程序,不建议对新的开发使用该技术。现在应该使用 Windows Communication Foundation (WCF) 来开发分布式应用程序。
远程处理旨在与具有强名称的程序集共同使用。当强名称用于远程处理时,下列基本规则适用:
版本始终包含在 IMethodCallMessage 接口实现的 TypeName 属性中。
版本始终包含在 IConstructionCallMessage 接口实现的 ActivationTypeName 属性中。
远程处理中的所有其他版本信息都由正在使用的格式化程序的 includeVersions 属性决定。默认情况下,BinaryFormatter 对象生成版本信息,而 SoapFormatter 对象则不。此属性可以在创建信道时以编程方式更改,或者可以通过远程处理配置文件进行设置。
本节将介绍这些规则如何影响对象引用,以及远程处理中常用的几种不同的激活模型。
服务器激活的对象
服务器控制当客户端连接到服务器激活的(或 <wellknown>)对象时类型的哪个版本被激活。如果配置服务时未提供版本信息,在激活对象时,将使用最新的程序集版本。例如,如果您有两个程序集:MyHello
1.0.0.0 版和 MyHello
2.0.0.0 版,那么如果未提供版本信息,则将使用 2.0 版程序集激活已知对象。请注意,不管生成客户端时引用的是哪个版本,都将使用此版本,这一点很重要。
可以将服务配置为使用特定版本的程序集。例如,下面的配置文件说明如何指定版本。请注意,如果程序集位于全局程序集缓存中,那么您必须指定所有类型信息,包括区域性信息和公钥。下面的配置示例省略了强名称信息以将精力集中在版本信息上。
<configuration>
<system.runtime.remoting>
<application name="RemotingHello">
<lifetime
leaseTime="20ms"
sponsorshipTimeOut="20ms"
renewOnCallTime="20ms"
/>
<service>
<wellknown
mode="SingleCall"
type="Hello.HelloService,MyHello,Version=1.0.0.0,<strong name omitted>"
objectUri="HelloService.soap"
/>
<activated
type="Hello.AddService, MyHello"
/>
</service>
<channels>
<channel
port="8000"
ref="tcp"
>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
此文件指定应该使用 1.0.0.0 版本的 MyHello
程序集来为其客户端创建对象。如果在终结点指定了同一个对象的多个版本,激活该对象时将使用最后指定的版本。请记住,同一个对象的不同版本间的任何重大更改都会对客户端产生不利影响,这一点很重要。如果在不同的版本间添加或修改了方法参数,在 1.0 版上使用针对 2.0 版编译的客户端时,便会引发异常。因此,建议当不同的版本间发生重大更改时,在其他终结点上承载新版本的对象。
客户端激活的对象
当客户端激活客户端激活的(即 <activated>)对象时,将会向激活请求的对象的服务器发送一个网络调用,并且对该对象的对象引用会返回到客户端。因为客户端指引对象的激活,因此它还会选择要激活的对象版本。例如,如果客户端是针对 1.0 版的对象生成的,那么在服务器上将激活 HelloService
1.0 版;如果客户端是针对 2.0 版生成的,那么在服务器上将激活 HelloService
2.0 版。
请注意,在配置服务时,您不能指定客户端激活的类型的版本号,这很重要。此外,为服务器激活的类型提供的任何版本信息都对客户端激活的对象没有影响,即使这两种类型在同一个程序集中也是如此。
例如,客户端激活类型和服务器激活类型位于同一个程序集中,您针对 1.0 版本生成了客户端 1,并针对 2.0 版本生成了客户端 2。如果没有为服务器激活对象指定版本信息,客户端 1 将接收 2.0 版的服务器激活对象以及 1.0 版的客户端激活对象。客户端 2 将接收已知和激活类型的 2.0 版对象。
如果您配置服务为已知对象使用 1.0 版程序集,那么两个客户端都将接收 1.0 版的已知对象,客户端 1 接收 1.0 版的激活类型,而客户端 2 接收 2.0 版的激活类型。
不能配置为客户端激活的版本,将始终使用针对其生成客户端的版本。
对象引用
适用于服务器激活类型和客户端激活类型的规则同样适用于对象引用。例如,如果将客户端激活类型的代理作为参数从一个客户端传递到另一个客户端,或者从客户端传递到服务器,嵌入在对象引用中的版本信息也会随之被传递。如果接收方尝试调用代理上由于对象引用而生成的方法,那么嵌入在对象引用中的版本优先于客户端针对其生成的版本。对于服务器激活的对象,服务器指出所用的版本以及将对象引用作为参数(与配置服务时指定的版本进行通信)接收的所有客户端。在没有任何版本信息时,将在服务器上激活最新版本。
按值封送对象
在应用程序域之间传递按值封送 (MBV) 对象时,所使用的格式化程序决定是否包括版本信息。BinaryFormatter 对象始终包括版本,而 SoapFormatter 对象则忽略版本信息。可以为这两个格式化程序启用或禁用此选项。例如,如果将下面一行添加到配置文件中,SoapFormatter 会在序列化对象时添加版本信息。
<formatter ref="soap" includeVersions="true" />