2010-10-12 28 views
1

我们正在开发一个CRM应用程序。所有业务逻辑和数据访问都通过WCF服务。我们有2个选项用于WCF和客户端之间的通信(目前为:ASP.NET MVC 2)WCF单个与多个操作?设计理念

一个选项是每个操作的创建方法。实施例

GetCustomers() 
    GetCustomersWithPaging(int take, int skip) 
    GetCustomersWithFilter(string filter) 
    GetCustomersWithFilterPaging(string filter, int take, int skip) 
    or // new .net 4 feature 
    GetCustomers(string filter = null, int take = 0, int skip = 0) 
    ... list goes.. 

另一个选择是创建名为

响应InvokeMessage(Messege请求)通用单一服务操作。实施例

wcfservice.InvokeMessage(
    new CustomerRequest { 
     Filter = "google", 
     Paging = new Page { take = 20, skip = 5} 
    }); 

// Service Implementation. 
public Response InvokeMessage(Message request) 
{ 
    return request.InvokeMessage(); 
} 

InvokeMessage =通用单一服务呼叫的所有操作。

CustomerRequest =从消息抽象类继承的类,所以可创建从Message基类的多个类依赖于输入的要求。 这是CustomerRequest类。

public class CustomerRequest : Message 
{ 
    public string Filter {get;set;} 
    public Page Paging {get;set} // Paging class not shown here. 
    Public override Response InvokeMessage() 
    { 
     // business logic and data access 
    } 
} 

编辑

public abstract class Message 
{ 
    public abstract Response InvokeMessage(); 
} 

//所有服务电话将通过InvokeMessage方法只,但具有不同的消息请求。

基本上我能避免各服务调用的和代理紧密等。 一个使用这种方法直接影响是,我不能使用这项服务作为REST

什么是推荐的方法,如果该服务需要调用大量的方法?

谢谢。

+2

我个人的看法是,设计一个伟大的WS通常会很困难。简单地将后端数据反馈到客户端是不够的。这真的归结为定义,而不是反刍。如果你有可能想要公开这个WS,不要去看InvokeMessage路由,但是如果这只是产品内部的一种通信形式,我认为它不重要。 – 2010-10-12 20:33:33

+0

它是内部的,但正如您在将来所说的那样,它可能需要向公众公开某些功能;我认为在这些情况下,最好通过WCF数据服务或类似方法公开有限的功能。谢谢你的评论。 – ash 2010-10-12 20:46:06

+0

我同意Aaron的设计伟大的WS是一项艰巨的任务。考虑到这一点,我会说现在不用担心“未来的一部分”。现在让您的服务为您的内部应用程序工作,并在您遇到问题时跨过桥梁。 – 2010-10-12 21:07:12

回答

2

如果您使用立面图案,您可以同时拥有两种立面图案。

首先,使用第一个选项构建您的服务。这允许你有一个REST接口。如果需要,可以在外部使用。

然后,您可以创建一个使用Invoke消息样式的外观,这会根据参数转换请求并调用第一步中创建的单个服务之一。

0

对于多个特定操作与一个一般查询的问题 - 两种方法都可能是有效的;定义细粒度和粗粒度操作在某种程度上是口味问题。

当面对我们的RESTful服务类似的要求,我选择创建一个过滤器类,它读取来自查询字符串参数,可正是如此:

public NameValueCollection ReadQuerystring() 
{ 
    return WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters; 
} 

更大的问题,我在这里看到的是你为你的操作参数子类化消息 - 你有这样做的原因吗?最佳做法是创建数据合同(用[DataContract]属性注释的对象)用于此目的。

+0

@why子类;我编辑我的原始帖子,以包含消息类与抽象方法,所以如果客户端需要新的请求示例:LatePayingCustomers(这些是实际上客户端看到它的数据契约),那么我需要从消息继承它以便通过“InvokeMessage” ,这反过来又称为LatePayingCustomers重写,这样我在两种方法中都得到了更好的错误处理。 – ash 2010-10-12 22:53:07