Контракты данных, совместимые с любыми будущими изменениями

Особенность системы контракта данных Windows Communication Foundation (WCF) заключается в том, что контракты могут развиваться с течением времени в неразрывных способах. Это значит, что клиент, использующий старую версию контракта данных, может взаимодействовать со службой, использующей новую версию того же контракта данных, или клиент, использующий новую версию контракта данных, может взаимодействовать со службой, использующей старую версию того же контракта данных. Дополнительные сведения см. в статье "Рекомендации по управлению версиями контракта данных".

Большинство возможностей управления версиями можно применять по мере необходимости при создании новых версий существующего контакта данных. Однако для правильной работы одной функции управления версиями необходимо встроить в тип из первой версии.

Полная совместимость версий

Полная совместимость версий обеспечивается, когда данные передаются от новой версии к старой и снова в новую версию контракта данных. Полная совместимость версий гарантирует сохранение всех данных. Включение полной совместимости версий обеспечивает прямую совместимость типа с любыми будущими изменениями, поддерживаемыми моделью управления версиями контрактов данных.

Полная совместимость версий для определенного типа возможна только в том случае, если этот тип реализует интерфейс IExtensibleDataObject. Интерфейс имеет одно свойство: ExtensionData (возвращение типа ExtensionDataObject). Это свойство сохраняет любые данные из будущих версий контракта данных, неизвестные в текущей версии.

Пример

Ниже представлен контракт данных, который не обладает прямой совместимостью с будущими изменениями.

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

Чтобы тип был совместим с будущими изменениями (такими как добавление нового члена данных с именем "phoneNumber"), необходимо реализовать интерфейс IExtensibleDataObject.

[DataContract]
public class Person : IExtensibleDataObject
{
    [DataMember]
    public string fullName;
    private ExtensionDataObject theData;

    public virtual ExtensionDataObject ExtensionData
    {
        get { return theData; }
        set { theData = value; }
    }
}
<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

Когда инфраструктура WCF обнаруживает данные, которые не являются частью исходного контракта данных, данные хранятся в свойстве и сохраняются. Обработка данных выполняется только во временном хранилище. Если объект возвращается в место создания, также возвращаются исходные (неизвестные) данные. Следовательно, данные совершают круговой путь к исходной конечной точке и из нее без потерь. Однако следует помнить, что если в исходной конечной точке необходимо выполнить обработку данных, этого не произойдет, и конечная точка должна будет каким-либо образом обнаружить и применить изменение.

Тип ExtensionDataObject не содержит открытых методов или свойств. Таким образом, невозможно получить прямой доступ к данным, хранящимся внутри свойства ExtensionData.

Функцию полной совместимости версий можно отключить, присвоив свойству ignoreExtensionDataObject значение true в конструкторе DataContractSerializer или присвоив свойству IgnoreExtensionDataObject значение true для атрибута ServiceBehaviorAttribute. Если эта возможность выключена, десериализатор не будет заполнять свойство ExtensionData, а сериализатор не будет выпускать содержимое свойства.

См. также