我有一个Windows WCF服务和Web客户端。我的服务有一种方法
[OperationContract]
SubmitOrder(OrderInfo info)....
// class used to pass all relevant data
[DataContract]
class OrderInfo
{
[DataMember]
OrderType Type;
// general order data
}
在我引入新订单类型(由OrderInfo.Type
属性控制)之前,这很棒。您可以将新订单类型视为从一般订单(行为方面)派生而来。
每个新订单都有一些额外的属性。什么是最好的方法
实现Order的这种多态行为?
目前,我只是在添加新订单时向OrderInfo类添加新属性。
[DataContract]
class OrderInfo
{
[DataMember]
OrderType Type;
// general order data
// First custom order data
// Second custom order data
// TODO - add new properties for new orders
}
我不喜欢它,因为它太直了。如果我更改[DataContract]和客户端怎么办? 没有重建?
我有什么选择?我当然可以实现继承并派生新的[DataContract]
类,如MyCustomOrder1
,但序列化不支持继承,我需要使用由于某些原因而被禁止的[KnownTypes]
。
答案 0 :(得分:5)
脱离我的头脑,我不确定这是一个好主意,但我认为这样做的一种方法是放松你在服务方面的合同,例如:改为使用MessageContract并接受消息中的“任何”内容。您仍然可以将您的数据交易分发给您的客户,这样您就可以根据模型对客户进行编程。在服务方面,您需要确定消息包含哪种内容并采取相应的行动。
我不确定如何实现这一点的细节,但我首先看一下WCF中的Message类:http://msdn.microsoft.com/en-us/library/ms734675.aspx
归结为使用“无类型”消息,如此处所述:http://geekswithblogs.net/claeyskurt/archive/2008/09/24/125430.aspx如前所述:WCF and Anonymous Types
完全不同的方式(可能更干净?)将使用IExtensibleDataObject,如本文http://geekswithblogs.net/claeyskurt/archive/2008/05/02/121848.aspx第2部分所述。
编辑:我正在阅读data contract versioning,我想到了什么是更好的解决方案
如果由于某种原因您无法使用KnownType,那么您所做的就是创建新版本的合同。最简单的方法是
现在,当您添加新类型时,将新属性添加到OrderInfo类,只要它们是可选的并且类的其余部分不会更改,您将向后兼容您的客户。还没有合同的新版本。是的,它可能会在客户端变得混乱,但你总是可以在一些辅助类之后抽象出来。
答案 1 :(得分:3)
我需要使用[KnownType] 由于某些原因被禁止。
禁止是什么意思?我使用KnownTypeAttribute
没有任何问题。这是一个例子。
[DataContract]
[KnownType( typeof( NetworkDeviceProperties ) )]
public class DeviceProperties
{
[DataMember]
public string MachineName { get; set; }
}
[DataContract]
public class NetworkDeviceProperties : DeviceProperties
{
[DataMember]
public IPAddress IPAddress { get; set; }
}
[ServiceContract]
public interface ICollectionService
{
[OperationContract]
[ServiceKnownType( typeof( NetworkDeviceProperties ) )]
void Start( DeviceProperties properties );
}
在我的客户端,我创建了一个NetworkDeviceProperties
对象并将其无问题地传递给Start()方法。有关其他信息,请参阅此blog。