リモート処理でのバージョン情報
リモート処理は、厳密な名前付きアセンブリで機能するようにデザインされました。厳密な名前をリモート処理で使用する場合は、次に示す基本的規則が適用されます。
バージョンは、常に IMethodCallMessage インターフェイス実装の TypeName プロパティに含まれています。
バージョンは、常に IConstructionCallMessage インターフェイス実装の ActivationTypeName プロパティに含まれています。
リモート処理でのその他すべてのバージョン管理は、使用されているフォーマッタの includeVersions プロパティによって決定されます。既定では、BinaryFormatter オブジェクトはバージョン管理情報を生成しますが、SoapFormatter オブジェクトはバージョン管理情報を生成しません。このプロパティは、チャネルを生成するときにプログラムを使用して変更したり、リモート処理構成ファイルを使用して設定したりできます。
このセクションでは、これらの規則がオブジェクト参照や、リモート処理で一般的に使用される各種のアクティベーション モデルに与える影響について説明します。
サーバー側でアクティブ化されるオブジェクト
サーバーは、サーバー側でアクティブ化される (つまり <wellknown>) オブジェクトにクライアントが接続したときに、どのバージョンがアクティブ化されるのかを制御します。サービスを構成するときにバージョン管理情報を提供しなかった場合、オブジェクトがアクティブ化されるときにアセンブリの最近のバージョンが使用されます。たとえば、バージョン情報が与えられていないとき、MyHello バージョン 1.0.0.0 と MyHello バージョン 2.0.0.0 という 2 つのアセンブリが存在すると、バージョン 2 のアセンブリを使用して既知のオブジェクトがアクティブ化されます。このバージョンは、クライアントが構築されたときに参照されたバージョンとは無関係に使用されることに注意する必要があります。
サービスは、特定のバージョンのアセンブリを使用して構成できます。構成ファイルを使用してバージョンを指定する例を次に示します。アセンブリがグローバル アセンブリ キャッシュに配置されている場合は、カルチャ情報や公開キーも含めて、すべての型情報を指定する必要があります。次に示す構成例では、バージョン管理に関する部分だけを示すために、厳密な名前情報は省略されています。
<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>
このファイルでは、クライアントに対してオブジェクトを生成するときに、MyHello
アセンブリのバージョン 1.0.0.0 を使用するように指定しています。エンドポイントで同じオブジェクトの複数のバージョンを指定すると、そのオブジェクトがアクティブ化されるときには、指定した最新のバージョンが使用されます。同じオブジェクトの複数のバージョン間で重要な変更を行うと、クライアントに望ましくない影響を与える可能性があることに注意する必要があります。複数のバージョン間でメソッド パラメータを追加または変更すると、バージョン 1 に対してコンパイルしたクライアントは、バージョン 2 に対して使用すると例外をスローします。そのため、複数のバージョン間で重要な変更を行った場合は、オブジェクトの新しいバージョンを別のエンドポイントでホストすることをお勧めします。
クライアント側でアクティブ化されるオブジェクト
クライアントが、クライアント側でアクティブ化される (つまり <activated>) オブジェクトをアクティブにすると、要求されたオブジェクトがアクティブ化されるサーバーに対してすぐにネットワーク呼び出しが送信され、そのオブジェクトに対するオブジェクト参照がクライアントに返されます。オブジェクトのアクティベーションはクライアントが指示するため、アクティブにするオブジェクトのバージョンもクライアントが選択します。たとえば、クライアントが HelloService のバージョン 1 に対して構築された場合には、このオブジェクトのバージョン 1 がサーバー上でアクティブ化されます。クライアントが HelloService のバージョン 2 に対して構築された場合には、バージョン 2 がサーバー上でアクティブ化されます。
サービスを構成する場合、クライアント側でアクティブ化されるオブジェクトのバージョン番号は指定できないことに注意する必要があります。また、サーバー側でアクティブ化されるオブジェクトに対して提供されたバージョン管理情報は、このオブジェクトがクライアント側でアクティブ化されるオブジェクトと同じアセンブリ内にある場合でも、クライアント側でアクティブ化されるオブジェクトには影響を与えません。
たとえば、同じアセンブリ内にクライアント側でアクティブ化されるオブジェクトとサーバー側でアクティブ化されるオブジェクトが存在し、クライアント 1 をバージョン 1 に対して構築し、クライアント 2 をバージョン 2 に対して構築するとします。この場合、サーバー側でアクティブ化されるオブジェクトに対してバージョン管理情報を指定しないと、クライアント 1 は、サーバー側でアクティブ化されるオブジェクトのバージョン 2 と、クライアント側でアクティブ化されるオブジェクトのバージョン 1 を受け取ります。クライアント 2 は、wellknown オブジェクトと activated オブジェクトの両方のバージョン 2 オブジェクトを受け取ります。
wellknown オブジェクトについてアセンブリのバージョン 1 を使用するようにサービスを構成すると、wellknown オブジェクトについては両方のクライアントがバージョン 1 を受け取るのに対して、activated オブジェクトについては、クライアント 1 はバージョン 1 を受け取り、クライアント 2 はバージョン 2 を受け取ります。
クライアントに対してアクティブ化されるバージョンは構成できず、クライアントの構築で使用されたバージョンが常に使用されます。
オブジェクト参照
サーバー側でアクティブ化されるオブジェクトおよびクライアント側でアクティブ化されるオブジェクトに適用される規則と同じ規則が、オブジェクト参照にも適用されます。たとえば、クライアント側でアクティブ化されるオブジェクトに対するプロキシが 1 つのクライアントから別のクライアントに、またはクライアントからサーバーにパラメータとして渡されると、オブジェクト参照に埋め込まれたバージョン管理情報も同時に渡されます。受信側がオブジェクト参照から生成されたプロキシ上のメソッドを呼び出すと、そのオブジェクト参照に埋め込まれたバージョンが、クライアントの構築に使用されたバージョンに優先します。サーバー側でアクティブ化されるオブジェクトの場合、使用されるバージョンはサーバーが指示し、オブジェクト参照をパラメータとして受け取るすべてのクライアントは、サービスを構成したときに指定したバージョンと通信します。バージョン管理を行わない場合、サーバー上では最新のバージョンがアクティブ化されます。
値渡しでマーシャリングされるオブジェクト
値渡しでマーシャリングされる (MBV : Marshal-By-Value) オブジェクトがアプリケーション ドメイン間で受け渡しされると、使用されているフォーマッタが、バージョン管理情報が含まれているかどうかを判断します。BinaryFormatter オブジェクトは常にバージョンを含んでいますが、SoapFormatter オブジェクトはバージョン管理情報を無視します。このオプションは、どちらのフォーマッタでも有効にしたり、無効にしたりできます。たとえば、次に示す行を構成ファイルに追加すると、SoapFormatter はオブジェクトをシリアル化するときに、バージョン管理情報を追加します。
<formatter ref="soap" includeVersions="true" />
参照
概念
リモート アプリケーションの構成
クライアント アクティベーション
サーバー アクティベーション