上位互換性のあるデータ コントラクト

Windows Communication Foundation (WCF) のデータ コントラクト システムの特徴の 1 つは、コントラクトが互換性に影響のない形で時間の経過に応じて変化できる点にあります。つまり、古いバージョンのデータ コントラクトを使用するクライアントが同じデータ コントラクトの新しいバージョンのサービスと通信すること、または新しいバージョンのデータ コントラクトを使用するクライアントが同じデータ コントラクトの古いバージョンと通信することが可能です。詳細については、次のトピックを参照してください。、「ベスト プラクティス : データ コントラクトのバージョン管理」を参照してください。

バージョン管理機能の大半は、既存のデータ コントラクトの新しいバージョンが作成されたときに、必要に応じて適用できます。ただし、"ラウンド トリップ" というバージョン管理機能は、正しく動作するように最初のバージョンから型に組み込んでおく必要があります。

ラウンド トリップ

ラウンド トリップは、データ コントラクトの新しいバージョンから古いバージョンにデータが渡され、新しいバージョンに戻されるときに発生します。ラウンド トリップでは、データの損失がないことが保証されます。ラウンド トリップを有効にすると、データ コントラクト バージョン管理モデルによってサポートされる将来の変更に関して、型の上位互換性が保たれます。

特定の型のラウンド トリップを有効にするには、この型に IExtensibleDataObject インターフェイスを実装する必要があります。このインターフェイスには、(ExtensionDataObject 型を返す) ExtensionData プロパティが含まれます。このプロパティにより、現在のバージョンでは未知の、今後使用されるデータ コントラクトの任意のデータが格納されます。

次のデータ コントラクトは、将来の変更に対して上位互換性がありません。

<DataContract()>  _
Public Class Person
    <DataMember()>  _
    Public fullName As String
End Class 
[DataContract]
public class Person
{
    [DataMember]
    public string fullName;
}

将来の変更 (たとえば、"phoneNumber" という名前の新しいデータ メンバーを追加する) に対して互換性を確保するには、IExtensibleDataObject インターフェイスを次のように実装します。

<DataContract()>  _
Public Class Person
    Implements IExtensibleDataObject
    <DataMember()>  _
    Public fullName As String
    Private theData As ExtensionDataObject
    
    
    Public Overridable Property ExtensionData() As _
     ExtensionDataObject Implements _
     IExtensibleDataObject.ExtensionData
        Get
            Return theData
        End Get
        Set
            theData = value
        End Set
    End Property
End Class 
[DataContract]
public class Person : IExtensibleDataObject
{
    [DataMember]
    public string fullName;
    private ExtensionDataObject theData;

    public virtual ExtensionDataObject ExtensionData
    {
        get { return theData; }
        set { theData = value; }
    }
}

WCF インフラストラクチャが、元のデータ コントラクトに含まれないデータを検出すると、このデータはプロパティに格納されて維持されます。データは一時的に格納されるだけで、処理されることはありません。オブジェクトを発生元に返すと、元の (未知の) データも返されます。したがって、データが失われることなく、元のエンドポイントとの間でラウンド トリップ (往復) が行われます。ただし、発生元のエンドポイントでデータを処理する必要がある場合、この要求は満たされないため、このエンドポイントでは何らかの方法で変更を検出して対応する必要があることに注意してください。

ExtensionDataObject 型にはパブリックなメソッドやプロパティはありません。そのため、ExtensionData プロパティ内に格納されているデータに直接アクセスすることはできません。

ラウンド トリップ機能は、DataContractSerializer コンストラクターで ignoreExtensionDataObjecttrue に設定する、または ServiceBehaviorAttributeIgnoreExtensionDataObject プロパティを true に設定することで無効にできます。この機能を無効にすると、デシリアライザーが ExtensionData プロパティを設定しないため、シリアライザーはプロパティの内容を出力しません。

参照

リファレンス

IExtensibleDataObject
ExtensionDataObject

概念

データ コントラクトのバージョン管理
ベスト プラクティス : データ コントラクトのバージョン管理