我有一个 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]
由于某些原因被禁止。
最佳答案
在我的脑海中,我不确定这是一个好主意,但我认为一种方法是放宽您在服务方面的契约(Contract),例如请改用 MessageContract 并接受消息中的“任何”内容。您仍然可以将您的数据契约(Contract)分发给您的客户,因此您可以获得针对模型对客户进行编程的好处。在服务端,您需要弄清楚消息包含什么样的内容并采取相应的行动。
我不确定如何实现它的细节,但我会首先查看 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,如本文第 2 部分所述 http://geekswithblogs.net/claeyskurt/archive/2008/05/02/121848.aspx .
编辑:我正在阅读关于 data contract versioning 的内容我想到了更好的解决方案
如果出于某种原因您不能使用 KnownType,那么您正在做的事情归结为创建新版本的契约(Contract)。最简单的开始方式是
- 创建一个包含所有子类型属性的订单信息合约
- 添加一个“类型”属性(一个字符串,因为您不能在之后添加新的枚举,这将是一个重大更改)
- 使基类上的所有属性成为“必需”
- 使子类型上的所有属性成为“可选”
- 实现 IExtensibleDataObject 以实现向前兼容
- 在我们的服务中,使用 type 属性来确定它是哪种顺序并据此采取行动
现在,当您添加新类型时,将新属性添加到 OrderInfo 类中,只要它们是可选的并且该类的其余部分不变,您就可以向后兼容您的客户还没有新版本的契约(Contract)。是的,它在客户端可能会变得困惑,但您始终可以将其抽象到一些辅助类后面。
关于c# - 服务 - 客户端界面、架构建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1907604/