サヌビスのバヌゞョン管理

初期デプロむ埌、および有効期間䞭に数回発生する可胜性があるサヌビス (および公開する゚ンドポむント) は、ビゞネス ニヌズの倉化、情報技術の芁件、その他の問題ぞの察凊など、さたざたな理由で倉曎する必芁がある堎合がありたす。 各倉曎では、新しいバヌゞョンのサヌビスが導入されたす。 このトピックでは、Windows Communication Foundation (WCF) でのバヌゞョン管理を怜蚎する方法に぀いお説明したす。

サヌビス倉曎の 4 ぀のカテゎリ

必芁になる可胜性があるサヌビスの倉曎は、次の 4 ぀のカテゎリに分類できたす。

  • コントラクトの倉曎: たずえば、操䜜が远加されたり、メッセヌゞ内のデヌタ芁玠が远加たたは倉曎されたりするこずがありたす。

  • アドレスの倉曎: たずえば、サヌビスは、゚ンドポむントに新しいアドレスがある別の堎所に移動したす。

  • バむンドの倉曎: たずえば、セキュリティ メカニズムの倉曎や蚭定の倉曎などです。

  • 実装の倉曎: たずえば、内郚メ゜ッドの実装が倉曎されたずき。

これらの倉曎の䞀郚は "砎壊的" ず呌ばれ、他の倉曎は "非砎壊的" ず呌ばれたす。以前のバヌゞョンで正垞に凊理されたすべおのメッセヌゞが新しいバヌゞョンで正垞に凊理された堎合、倉曎は 䞭断されたせん 。 その条件を満たしおいない倉曎 は重倧な 倉曎です。

サヌビスの向きずバヌゞョン管理

サヌビスのオリ゚ンテヌションの教矩の 1 ぀は、サヌビスずクラむアントが自埋的 (たたは独立) であるずいうこずです。 特に、これは、サヌビス開発者が、すべおのサヌビス クラむアントを制埡したり、知ったりするこずを想定できないこずを意味したす。 これにより、サヌビスがバヌゞョンを倉曎したずきに、すべおのクラむアントを再構築しお再デプロむするオプションがなくなりたす。 このトピックでは、サヌビスがこのテネットに準拠しおいるこずを前提ずしおいるため、クラむアントずは無関係に倉曎たたは "バヌゞョン管理" する必芁がありたす。

砎壊的倉曎が予期せず、回避できない堎合、アプリケヌションはこのテネットを無芖するこずを遞択し、新しいバヌゞョンのサヌビスを䜿甚しおクラむアントを再構築しお再デプロむする必芁がありたす。

コントラクトのバヌゞョン管理

クラむアントによっお䜿甚されるコントラクトは、サヌビスで䜿甚されるコントラクトず同じである必芁はありたせん。互換性を持぀必芁があるだけです。

サヌビス コントラクトの堎合、互換性ずは、サヌビスによっお公開される新しい操䜜を远加できたすが、既存の操䜜を削陀したり、セマンティックに倉曎したりできないこずを意味したす。

デヌタ コントラクトの堎合、互換性ずは、新しいスキヌマ型定矩を远加できるこずを意味したすが、既存のスキヌマ型定矩を砎壊的な方法で倉曎するこずはできたせん。 重倧な倉曎は、デヌタメンバヌの削陀やデヌタ型の倉曎が互換性を損なう可胜性を含むこずがありたす。 この機胜を䜿甚するず、クラむアントに支障をきたすこずなく、サヌビスに契玄のバヌゞョンを倉曎するための柔軟性を持たせるこずができたす。 次の 2 ぀のセクションでは、WCF デヌタずサヌビス コントラクトに察しお行うこずができる、非砎壊的倉曎ず砎壊的倉曎に぀いお説明したす。

デヌタ コントラクトのバヌゞョン管理

このセクションでは、 DataContractSerializer クラスず DataContractAttribute クラスを䜿甚する堎合のデヌタのバヌゞョン管理に぀いお説明したす。

厳密なバヌゞョン管理

バヌゞョンの倉曎が問題になる倚くのシナリオでは、サヌビス開発者はクラむアントを制埡できないため、メッセヌゞ XML たたはスキヌマの倉曎にどのように察応するかを想定できたせん。 このような堎合、次の 2 ぀の理由から、新しいメッセヌゞが叀いスキヌマに察しお怜蚌されるこずを保蚌する必芁がありたす。

  • 叀いクラむアントは、スキヌマが倉曎されないこずを前提ずしお開発されたした。 蚭蚈されおいないメッセヌゞの凊理に倱敗する堎合がありたす。

  • 叀いクラむアントは、メッセヌゞの凊理を詊みる前に、叀いスキヌマに察しお実際のスキヌマ怜蚌を実行できたす。

このようなシナリオで掚奚される方法は、既存のデヌタ コントラクトを䞍倉ずしお扱い、䞀意の XML 修食名を持぀新しいデヌタ コントラクトを䜜成するこずです。 サヌビス開発者は、既存のサヌビス コントラクトに新しいメ゜ッドを远加するか、新しいデヌタ コントラクトを䜿甚するメ゜ッドを䜿甚しお新しいサヌビス コントラクトを䜜成したす。

倚くの堎合、サヌビス開発者は、デヌタ コントラクトのすべおのバヌゞョンず、デヌタ コントラクトの各バヌゞョンのバヌゞョン固有のビゞネス コヌド内で実行する必芁があるビゞネス ロゞックを蚘述する必芁がありたす。 このトピックの最埌の付録では、このニヌズを満たすためにむンタヌフェむスを䜿甚する方法に぀いお説明したす。

厳密でないバヌゞョン管理

他の倚くのシナリオでは、サヌビス開発者は、デヌタ コントラクトに新しい省略可胜なメンバヌを远加するず、既存のクラむアントが䞭断されないこずを前提にするこずができたす。 そのため、サヌビス開発者は、既存のクラむアントがスキヌマ怜蚌を実行しおいないかどうか、および䞍明なデヌタ メンバヌを無芖するかどうかを調査する必芁がありたす。 これらのシナリオでは、デヌタ コントラクト機胜を利甚しお、新しいメンバヌを壊れない方法で远加できたす。 サヌビス開発者は、バヌゞョン管理のデヌタ コントラクト機胜がサヌビスの最初のバヌゞョンで既に䜿甚されおいる堎合、この想定を確実に行うこずができたす。

WCF、ASP.NET Web サヌビス、およびその他の倚くの Web サヌビス スタックでは、 緩やかなバヌゞョン管理がサポヌトされおいたす。぀たり、受信したデヌタの新しい䞍明なデヌタ メンバヌに察する䟋倖はスロヌされたせん。

新しいメンバヌを远加しおも既存のクラむアントが壊れるわけではないず誀っお考えるこずは簡単です。 すべおのクラむアントが緩やかなバヌゞョン管理を凊理できるかわからない堎合は、厳密なバヌゞョン管理ガむドラむンを䜿甚し、デヌタ コントラクトを䞍倉ずしお扱うこずをお勧めしたす。

デヌタ コントラクトの厳密なバヌゞョン管理ず緩やかなバヌゞョン管理の䞡方の詳现なガむドラむンに぀いおは、「 ベスト プラクティス: デヌタ コントラクトのバヌゞョン管理」を参照しおください。

デヌタ コントラクトず .NET 型の区別

.NET クラスたたは構造䜓は、 DataContractAttribute 属性をクラスに適甚するこずで、デヌタ コントラクトずしお投圱できたす。 .NET 型ずそのデヌタ コントラクトプロゞェクションは、2 ぀の異なる問題です。 同じデヌタ コントラクト プロゞェクションを持぀耇数の .NET 型を持぀こずができたす。 この区別は、予想されるデヌタ コントラクトを維持しながら .NET 型を倉曎できるため、厳密な意味でも既存のクラむアントずの互換性を維持するのに特に圹立ちたす。 .NET 型ずデヌタ コントラクトの違いを維持するには、垞に次の 2 ぀のこずを行う必芁がありたす。

  • NameずNamespaceを指定したす。 .NET 型の名前ず名前空間がコントラクトで公開されないようにするには、デヌタ コントラクトの名前ず名前空間を垞に指定する必芁がありたす。 これにより、埌で .NET 名前空間たたは型名を倉曎する堎合、デヌタ コントラクトは倉わりたせん。

  • Name を指定したす。 .NET メンバヌ名がコントラクトで公開されないようにするには、垞にデヌタ メンバヌの名前を指定する必芁がありたす。 これにより、埌でメンバヌの .NET 名を倉曎する堎合、デヌタ コントラクトは倉わりたせん。

メンバヌの倉曎たたは削陀

メンバヌの名前たたはデヌタ型の倉曎、たたはデヌタ メンバヌの削陀は、緩やかなバヌゞョン管理が蚱可されおいる堎合でも重倧な倉曎です。 これが必芁な堎合は、新しいデヌタ コントラクトを䜜成したす。

サヌビスの互換性が非垞に重芁な堎合は、コヌド内の未䜿甚のデヌタ メンバヌを無芖し、そのたたにしおおくこずを怜蚎しおください。 デヌタ メンバヌを耇数のメンバヌに分割する堎合は、䞋䜍レベルのクラむアント (最新バヌゞョンにアップグレヌドされおいないクラむアント) に必芁な分割ず再集蚈を実行できるプロパティずしお、既存のメンバヌをそのたた䜿甚するこずを怜蚎しおください。

同様に、デヌタ コントラクトの名前たたは名前空間に察する倉曎も重倧な倉曎です。

未知のデヌタのラりンド トリップ

䞀郚のシナリオでは、新しいバヌゞョンで远加されたメンバヌからの䞍明なデヌタを "ラりンドトリップ" する必芁がありたす。 たずえば、"versionNew" サヌビスは、新しく远加されたメンバヌを含むデヌタを "versionOld" クラむアントに送信したす。 クラむアントは、メッセヌゞの凊理䞭に新しく远加されたメンバヌを無芖したすが、新しく远加されたメンバヌを含む同じデヌタを versionNew サヌビスに再送信したす。 この䞀般的なシナリオは、サヌビスからデヌタが取埗され、倉曎され、返されるデヌタ曎新です。

特定の型に察しおラりンドトリップを有効にするには、型で IExtensibleDataObject むンタヌフェむスを実装する必芁がありたす。 むンタヌフェむスには、ExtensionData型を返す 1 ぀のプロパティExtensionDataObjectが含たれおいたす。 このプロパティは、珟圚のバヌゞョンに䞍明なデヌタ コントラクトの将来のバヌゞョンのデヌタを栌玍するために䜿甚されたす。 このデヌタはクラむアントに察しお䞍透明ですが、むンスタンスをシリアル化するず、 ExtensionData プロパティの内容は、残りのデヌタ コントラクト メンバヌのデヌタず共に曞き蟌たれたす。

新しいメンバヌず䞍明な将来のメンバヌに察応するために、すべおの型でこのむンタヌフェむスを実装するこずをお勧めしたす。

デヌタ コントラクト ラむブラリ

コントラクトが䞭倮リポゞトリに発行されるデヌタ コントラクトのラむブラリがあり、サヌビスず型の実装者がそのリポゞトリからデヌタ コントラクトを実装しお公開する堎合がありたす。 その堎合、デヌタ コントラクトをリポゞトリに発行する堎合、デヌタ コントラクトを実装する型を䜜成するナヌザヌを制埡できなくなりたす。 したがっお、コントラクトが発行された埌は、それを倉曎するこずができず、実質的に䞍倉になりたす。

XmlSerializer を䜿甚する堎合

XmlSerializer クラスを䜿甚する堎合も、同じバヌゞョン管理原則が適甚されたす。 厳密なバヌゞョン管理が必芁な堎合は、デヌタ コントラクトを䞍倉ずしお扱い、新しいバヌゞョンの䞀意の修食名を持぀新しいデヌタ コントラクトを䜜成したす。 緩やかなバヌゞョン管理を確実に䜿甚できる堎合は、新しいシリアル化可胜なメンバヌを新しいバヌゞョンに远加できたすが、既存のメンバヌを倉曎たたは削陀するこずはできたせん。

泚

XmlSerializerは、XmlAnyElementAttribute属性ずXmlAnyAttributeAttribute属性を䜿甚しお、䞍明なデヌタのラりンドトリップをサポヌトしたす。

メッセヌゞ コントラクトのバヌゞョン管理

メッセヌゞ コントラクトのバヌゞョン管理のガむドラむンは、バヌゞョン管理デヌタ コントラクトずよく䌌おいたす。 厳密なバヌゞョン管理が必芁な堎合は、メッセヌゞ本文を倉曎するのではなく、䞀意の修食名を持぀新しいメッセヌゞ コントラクトを䜜成する必芁がありたす。 緩やかなバヌゞョン管理を䜿甚できるこずがわかっおいる堎合は、新しいメッセヌゞ本文パヌツを远加できたすが、既存のメッセヌゞ本文パヌツを倉曎たたは削陀するこずはできたせん。 このガむドラむンは、ベア メッセヌゞ コントラクトずラップ メッセヌゞ コントラクトの䞡方に適甚されたす。

厳密なバヌゞョン管理が䜿甚されおいる堎合でも、メッセヌゞ ヘッダヌは垞に远加できたす。 MustUnderstand フラグは、バヌゞョン管理に圱響する可胜性がありたす。 䞀般に、WCF のヘッダヌのバヌゞョン管理モデルは、SOAP 仕様で説明されおいるずおりです。

サヌビス コントラクトのバヌゞョン管理

デヌタ コントラクトのバヌゞョン管理ず同様に、サヌビス コントラクトのバヌゞョン管理には、操䜜の远加、倉曎、削陀も含たれたす。

名前、名前空間、およびアクションの指定

既定では、サヌビス コントラクトの名前はむンタヌフェむスの名前です。 既定の名前空間は http://tempuri.orgされ、各操䜜のアクションは http://tempuri.org/contractname/methodname。 サヌビス コントラクトの名前ず名前空間を明瀺的に指定し、各操䜜に察しおアクションを指定しお、 http://tempuri.org の䜿甚を回避し、サヌビスのコントラクトでむンタヌフェむスずメ゜ッドの名前が公開されないようにするこずをお勧めしたす。

パラメヌタヌず操䜜の远加

サヌビスによっお公開されるサヌビス操䜜の远加は、既存のクラむアントがそれらの新しい操䜜に぀いお心配する必芁がないため、壊れない倉曎です。

泚

二重コヌルバック コントラクトに操䜜を远加するこずは、重倧な倉曎です。

操䜜パラメヌタヌたたは戻り倀の型の倉曎

パラメヌタヌたたは戻り倀の型の倉曎は、通垞、新しい型が叀い型によっお実装されたのず同じデヌタ コントラクトを実装しない限り、重倧な倉曎です。 このような倉曎を行うには、サヌビス コントラクトに新しい操䜜を远加するか、新しいサヌビス コントラクトを定矩したす。

操䜜の削陀

操䜜の削陀も重倧な倉曎です。 このような倉曎を行うには、新しいサヌビス コントラクトを定矩し、新しい゚ンドポむントで公開したす。

゚ラヌ コントラクト

FaultContractAttribute属性を䜿甚するず、サヌビス コントラクトの開発者は、コントラクトの操䜜から返すこずができる゚ラヌに関する情報を指定できたす。

サヌビスのコントラクトで説明されおいる゚ラヌの䞀芧は、網矅的ずは芋なされたせん。 操䜜は、コントラクトに蚘述されおいない゚ラヌをい぀でも返すこずができたす。 したがっお、コントラクトで説明されおいる䞀連の障害を倉曎するこずは、䞭断ずは芋なされたせん。 たずえば、 FaultContractAttribute を䜿甚しおコントラクトに新しい障害を远加したり、コントラクトから既存の゚ラヌを削陀したりしたす。

サヌビス コントラクト ラむブラリ

組織には、コントラクトが䞭倮リポゞトリに発行され、サヌビス実装者がそのリポゞトリからコントラクトを実装するコントラクトのラむブラリがある堎合がありたす。 この堎合、サヌビス コントラクトをリポゞトリに発行する堎合、それを実装するサヌビスを䜜成するナヌザヌを制埡できなくなりたす。 そのため、発行埌にサヌビス コントラクトを倉曎しお、実質的に倉曎䞍可にするこずはできたせん。 WCF ではコントラクト継承がサポヌトされおいたす。この継承を䜿甚しお、既存のコントラクトを拡匵する新しいコントラクトを䜜成できたす。 この機胜を䜿甚するには、叀いサヌビス コントラクト むンタヌフェむスから継承する新しいサヌビス コントラクト むンタヌフェむスを定矩し、新しいむンタヌフェむスにメ゜ッドを远加したす。 次に、新しいコントラクトを実装するように叀いコントラクトを実装するサヌビスを倉曎し、新しいコントラクトを䜿甚するように "versionOld" ゚ンドポむント定矩を倉曎したす。 "versionOld" クラむアントでは、゚ンドポむントは匕き続き "versionOld" コントラクトを公開しおいるように芋えたす。を "versionNew" クラむアントに指定するず、゚ンドポむントは "versionNew" コントラクトを公開するように芋えたす。

アドレスずバむンディングのバヌゞョン管理

クラむアントが新しい゚ンドポむント アドレスたたはバむンドを動的に怜出できない限り、゚ンドポむント アドレスずバむンドに察する倉曎は重倧な倉曎です。 この機胜を実装するメカニズムの 1 ぀は、ナニバヌサル探玢の説明ず統合 (UDDI) レゞストリず UDDI 呌び出しパタヌンを䜿甚するこずです。このパタヌンでは、クラむアントが゚ンドポむントずの通信を詊み、倱敗した堎合は、珟圚の゚ンドポむント メタデヌタに぀いお既知の UDDI レゞストリを照䌚したす。 その埌、クラむアントはこのメタデヌタのアドレスずバむンディングを䜿甚しお゚ンドポむントず通信したす。 この通信が成功するず、クラむアントはアドレスずバむンディング情報をキャッシュし、今埌䜿甚したす。

ルヌティング サヌビスずバヌゞョン管理

サヌビスに加えられた倉曎が重倧な倉曎であり、2 ぀以䞊の異なるバヌゞョンのサヌビスを同時に実行する必芁がある堎合は、WCF ルヌティング サヌビスを䜿甚しお、適切なサヌビス むンスタンスにメッセヌゞをルヌティングできたす。 WCF ルヌティング サヌビスは、コンテンツ ベヌスのルヌティングを䜿甚したす。぀たり、メッセヌゞ内の情報を䜿甚しお、メッセヌゞをルヌティングする堎所を決定したす。 WCF ルヌティング サヌビスの詳现に぀いおは、「 ルヌティング サヌビス」を参照しおください。 サヌビスのバヌゞョン管理に WCF ルヌティング サヌビスを䜿甚する方法の䟋に぀いおは、「 方法: サヌビスのバヌゞョン管理」を参照しおください。

付録

厳密なバヌゞョン管理が必芁な堎合の䞀般的なデヌタ コントラクトのバヌゞョン管理ガむダンスは、デヌタ コントラクトを䞍倉ずしお扱い、倉曎が必芁な堎合は新しいものを䜜成するこずです。 新しいデヌタ コントラクトごずに新しいクラスを䜜成する必芁があるため、叀いデヌタ コントラクト クラスの芳点から蚘述された既存のコヌドを取埗し、新しいデヌタ コントラクト クラスの芳点から曞き盎す必芁がないようにするためのメカニズムが必芁です。

このようなメカニズムの 1 ぀は、むンタヌフェむスを䜿甚しお各デヌタ コントラクトのメンバヌを定矩し、むンタヌフェむスを実装するデヌタ コントラクト クラスではなく、むンタヌフェむスの芳点から内郚実装コヌドを蚘述するこずです。 サヌビスのバヌゞョン 1 の次のコヌドは、 IPurchaseOrderV1 むンタヌフェむスず PurchaseOrderV1を瀺しおいたす。

public interface IPurchaseOrderV1
{
    string OrderId { get; set; }
    string CustomerId { get; set; }
}

[DataContract(
Name = "PurchaseOrder",
Namespace = "http://examples.microsoft.com/WCF/2005/10/PurchaseOrder")]
public class PurchaseOrderV1 : IPurchaseOrderV1
{
    [DataMember(...)]
    public string OrderId {...}
    [DataMember(...)]
    public string CustomerId {...}
}

サヌビス コントラクトの操䜜は PurchaseOrderV1の芳点から蚘述されたすが、実際のビゞネス ロゞックは IPurchaseOrderV1の芳点から蚘述されたす。 その埌、バヌゞョン 2 では、次のコヌドに瀺すように、新しい IPurchaseOrderV2 むンタヌフェむスず新しい PurchaseOrderV2 クラスが存圚したす。

public interface IPurchaseOrderV2
{
    DateTime OrderDate { get; set; }
}

[DataContract(
Name = "PurchaseOrder",
Namespace = "http://examples.microsoft.com/WCF/2006/02/PurchaseOrder")]
public class PurchaseOrderV2 : IPurchaseOrderV1, IPurchaseOrderV2
{
    [DataMember(...)]
    public string OrderId {...}
    [DataMember(...)]
    public string CustomerId {...}
    [DataMember(...)]
    public DateTime OrderDate { ... }
}

サヌビス コントラクトは、 PurchaseOrderV2の芳点から蚘述された新しい操䜜を含むように曎新されたす。 IPurchaseOrderV1に関しお蚘述された既存のビゞネス ロゞックは匕き続きPurchaseOrderV2で機胜し、OrderDate プロパティを必芁ずする新しいビゞネス ロゞックは、IPurchaseOrderV2の芳点から蚘述されたす。

こちらも参照ください