views:

58

answers:

2

We are developing a CRM application. All the business logic and data access go through WCF services. We have 2 options for communication between WCF and client (at the moment: ASP.NET MVC 2)

One option is create method for each operations. Example

    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..

Another option is create a generic single service operation called

Response InvokeMessage(Messege request). Example

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

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

InvokeMessage = generic single service call for all operation.

CustomerRequest = Inherited class from Message abstract class, so I can create multiple classes from Message base class depend on the input requirements. Here is the CustomerRequest class.

 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
   }
 } 

EDIT

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

// all service call will be through InvokeMessage method only, but with different message requests.

Basically I could avoid each service call's and proxy close etc.. One immediate implication with this approach is I cannot use this service as REST

What is the recommended approach if the service needs to call lots of methods?

thanks.

+1  A: 

If you use the facade pattern you can have both.

First, build your services using the first option. This allows you to have a REST interface. This can be used externally if required.

You can then create a facade that uses Invoke message style, this translates the request based on the parameters and calls one of the individual services created in the first step.

Shiraz Bhaiji
A: 

As to the question of multiple specific operations vs one general query - either approach could be valid; defining fine-grained vs coarse-grained operations is to some degree a matter of taste.

When faced with a similar requirement in our RESTful service, I've chosen to create a filter class that reads parameters from the query-string, available thusly:

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

The larger issue that I see here is that you're subclassing Message for your operation parameters - is there a reason why you're doing that? The best practice is to create data contracts (objects annotated with [DataContract] attributes) for such a purpose.

Ben
@why subclass; I edited my original post to include Message class with abstract method, So If client need new request example: LatePayingCustomers (these are data contracts actually so client see it), then I need to inherited it from Message in order to pass through "InvokeMessage", which in turn call LatePayingCustomers override, this way I get better error handling in both methods.
ash