c# - 服务 - 客户端界面、架构建议

标签 c# design-patterns inheritance serialization polymorphism

我有一个 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/

相关文章:

c# - 无论 .NET 版本如何,使用相同种子第 n 次调用 Random.Next() 是否总是产生相同的数字?

c# - Windows 上是否有 posix SIGTERM 替代方案? -(控制台应用程序的温和杀戮)

java - 针对多种模式验证字符串的最佳方法

java - Hadoop 单例模式的使用

C# - 从第三方库导入类并使其成为派生类(或类似的类)

c# - 加载网页时,如何让 CefSharp 隐藏垂直和水平滚动条?

c# - SQL CPU 高 - SqlConnection 未关闭 - 相关?

java - 使用工厂方法模式而不是简单工厂的动机是什么

c# - 对继承类的最小起订量测试总是返回 null

c++ - C++模板类-继承调用错误的函数