我试图弄清楚IExtensibleDataObject和IExtensibleObject之间的区别是什么。

MSDN表示,第一个(IExtensibleDataObject)是为了使可能添加了属性的对象反序列化,而第二个(IExtensibleObject)看起来非常相似,它也确实使对象添加了属性。

我很困惑。

最佳答案

IExtensibleDataObject与序列化有关,可以在WCF的服务堆栈之外使用。它的主要目的是在不丢失信息的情况下往返传输数据合约的不同版本。例如,在契约(Contract)的第一个版本中,您具有以下类型:

[DataContract(Name = "Person")]
public class Person : IExtensibleDataObject {
   ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }
   [DataMember(Order = 0)] public string Name;
   [DataMember(Order = 1)] public int Age;
}

您使用这种数据类型部署服务,并且有一些客户端使用这种数据类型。某些服务操作将Person返回到客户端,并且客户端可以将那些对象发送回服务,如以下示例所示。
[ServiceContract]
public interface ITest {
    [OperationContract] Person[] GetAllPeople();
    [OperationContract] void DoSomething(Person person);
}

一切都很好,直到业务逻辑发生变化要求将新成员添加到Person,并且支持数据库要求存在该字段(不为null)之前,一切都很好。
[DataContract(Name = "Person")]
public class Person_V2 : IExtensibleDataObject {
   ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }
   [DataMember(Order = 0)] public string Name;
   [DataMember(Order = 1)] public int Age;
   [DataMember(Order = 2)] public string Address;
}

如果没有IExtensibleDataObject,则现有客户端将接收Person对象,填充其Name/Age属性,并立即丢弃传递给它的Address元素。并且当它使用该对象调用DoSomething方法时,它将传递一个在服务器上无效的实例(地址为null)。

IEDO所做的就是启用这种情况,即现有(旧版)客户端可以继续从服务中接收数据契约(Contract)的新版本-客户端将使用服务中的数据以及它不了解的那些元素填充其了解的字段将存储在ExtensionDataObject中,以便以后可以重新序列化。在上面的示例中,旧版客户端将只能读取Person的Name和Age属性,但是当它将对象发送回服务器时,序列化的数据将包含所有这三个属性。

关于IEDO,这是一个漫长的故事。 IExtensibleObject与序列化无关-关于将扩展连接到WCF服务堆栈(主机,操作上下文,实例上下文和上下文 channel )中的一些预定义对象。不如IEDO有趣,所以我在这里停下来:)

编辑后的:出于完整性考虑,如果您想了解有关IExtensibleObject的更多信息,可以在http://blogs.msdn.com/b/carlosfigueira/archive/2012/01/31/wcf-extensibility-iextension-and-iextensibleobject.aspx上查看该帖子。

10-08 13:17