服务 - 客户端界面,架构建议 [英] Service - client interface, architecture advice

查看:105
本文介绍了服务 - 客户端界面,架构建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Windows WCF服务和Web客户端。我的服务有一种方法

  [OperationContract] 
SubmitOrder(OrderInfo信息)....

//用于传递所有相关数据的类
[DataContract]
class OrderInfo
{
[DataMember]
OrderType类型;
//一般订单数据
}

直到我介绍新订单类型(由 OrderInfo.Type 属性控制)。您可以将新订单类型视为从一般订单派生(在行为方面)。
每个新订单都有一些额外的属性。
的最佳方法是执行Order的多态行为?



目前,我只是在添加新订单时向OrderInfo类添加新的属性。

  [DataContract] 
class OrderInfo
{
[DataMember]
OrderType Type;
//一般订单数据

//第一个自定义订单数据
//第二个自定义订单数据
// TODO - 为新订单添加新属性
}

我不太喜欢它太直接了。如果我更改[DataContract]并且客户端
不被重建怎么办?



我的替代品是什么?我当然可以实现继承,并导出新的 [DataContract] 类,如 MyCustomOrder1 ,但序列化不支持继承,由于某些原因,我需要使用 [KnownTypes]

解决方案

在我的头顶,我不知道这是一个好主意,但我认为这样做的一个方法是放松你在服务方面的合同,例如使用MessageContract代替,并接受消息中的任何内容。您仍然可以将数据挖掘分发给客户端,因此您可以根据模型对客户端进行编程。在服务方面,您需要确定消息中包含什么样的内容,并相应地采取行动。



我不知道如何实现这一点,但是我先从WCF中的Message类开始: http:/ /msdn.microsoft.com/en-us/library/ms734675.aspx



它归结为使用无类型消息,如下所述: http://geekswithblogs.net/claeyskurt/archive/2008/09/24/ 125430.aspx ,如前所述: WCF和匿名类型






一个完全不同的方式(可能更清洁?)要使用IExtensibleDataObject,如本文的第2部分所述HREF =http://geekswithblogs.net/claeyskurt/ archive / 2008/05/02 / 121848.aspxrel =nofollow noreferrer> http://geekswithblogs.net/claeyskurt/archive/2008/05/02/121848.aspx 。






编辑:我在阅读关于数据合约版本控制,我想到了什么可以是更好的解决方案



如果由于任何原因您无法使用KnownType,您正在做的是归结为创建新版本的合同。最简单的开始方式是将




  • 与子类型的所有属性创建一个orderinfo合约

  • 添加一个'type'属性(一个字符串,因为你不能仅仅添加新的枚举,这将是一个突破性的变化)

  • 使所有属性在基类必需

  • 使子类型可选

  • 的所有属性实现IExtensibleDataObject为前向兼容

  • 在我们的服务中,使用type属性来确定它是什么类型的顺序,并相应地执行



现在当您添加新类型时,将新属性添加到OrderInfo类中,只要它们是可选的,而其余的类不会更改,那么您将向后兼容您的客户端您的合同的新版本。是的,它可能会在客户端发生混乱,但是您可以随时将其抽出一些助手课程。


I have a Windows WCF serivce and Web client. My service has one method

[OperationContract]
SubmitOrder(OrderInfo info)....

// class used to pass all relevant data
[DataContract]
class OrderInfo
{
 [DataMember]
 OrderType Type;
 // general order data
}

It was great until I have introduced new order types (controlled by OrderInfo.Type property). You can think of new order type as derived from general order (in terms of behaviour). Each new order has some additional properties. What is the best approach to implement this polymorphic behaviour of Order?

Currently I simply add new properties to OrderInfo class while adding new orders.

[DataContract]
class OrderInfo
{
 [DataMember]
 OrderType Type;
 // general order data

 // First custom order data
 // Second custom order data
 // TODO - add new properties for new orders
}

I don't like it much cause it too straight. What if I change [DataContract] and the client is not rebuilt?

What are my alternatives? I can of course implement inheritance and derive new [DataContract] class like MyCustomOrder1, but inheritance is not supported by serialization, I need to use [KnownTypes] which is forbidden due to some reasons.

解决方案

Off the top of my head and I'm not sure this is a great idea, but I think a way to do this would be to relax your contracts on the service side, e.g. use a MessageContract instead and accept 'any' content in the message. You can still distribute your datacontracts to your clients, so you have the benefit of programming your client against a model. On the service side, you then need to figure out what kind of content the message contains and act accordingly.

I'm not sure about the details of how to implement this, but I'd start by looking at the Message class in WCF: http://msdn.microsoft.com/en-us/library/ms734675.aspx

It boils down to using 'untyped' messages as explained here: http://geekswithblogs.net/claeyskurt/archive/2008/09/24/125430.aspx as previously discussed here: WCF and Anonymous Types


A completely different way (and maybe cleaner?) to do this would be to use IExtensibleDataObject as explained in part 2 of this post http://geekswithblogs.net/claeyskurt/archive/2008/05/02/121848.aspx.


edit: I was reading about data contract versioning and I thought of what could be a better solution

If for whatever reason you can't use KnownType, what you're doing boils down to creating new versions of your contract. The easiest way to start would be to

  • create a single orderinfo contract with all the properties of the subtypes
  • add a 'type' property (a string, because you can't just add new enumerations afterwards, this would be a breaking change)
  • make all the properties that were on the base class 'required'
  • make all the properties that were on the subtypes 'optional'
  • implement IExtensibleDataObject to be forward-compatible
  • in our service, use the type property to determine what kind of order it is and act accordingly

Now, when you're adding new types, add the new properties to the OrderInfo class, and as long as they are optional and the rest of the class doesn't change, you'll be backwards compatible with your clients who don't have the new version of your contract yet. Yes, it could get messy on the client side, but you can always abstract this away behind some helper classes.

这篇关于服务 - 客户端界面,架构建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆