0

i am new but reading some article on wcf i came to know that if you change the ServcieContrcat then you have to change not only the Service end but Clients end too and it's really difficult to manage.

Example 1:

Developer have to create WCF service for Order processing, with following function: GetOrderById, GetOrdersByStatus, SaveOrder

The ServiceContract could looks like following

[ServiceContract]
public interface IOrderService
{
    [OperationContract]
    Order GetOrderById(int orderId);

    [OperationContract]
    List<Order> GetOrdersByStatus(OrderStatus orderStatus);

    [OperationContract]
    void SaveOrder(Order order)
} 

after month, for example, project manager say: Ok, our customers need another functions: DeleteOrderById, GetOrdersByCustomerId and don't need GetOrdersByStatus any more, we need GetOrdersByStatusAndCustomerId

Developers have to update ServiceContrcat and update client. As you can see, any changes in the ServiceContrcat is really difficult

so i am looking for best guidance how to develop wcf service which will not create any problem if we extend the functionality or any kind of change but client end will not face any problem. thanks

Abbas
  • 14,186
  • 6
  • 41
  • 72
Thomas
  • 33,544
  • 126
  • 357
  • 626
  • You should extract the WCF contract bits into a library that both projects depend upon, it would then be a matter of updating once. – Machinarius Jan 23 '14 at 11:13

1 Answers1

0

enter image description hereI had the same problem, basically a perpetual set of changes to methods that would break the interfaces on the clients.

This is what I did: All of my 30+ functions (and the list grows and grows) took strings, ints and bytes() as data types as both input and output parameters, I created a master single endpoint and function that receives, as an input parameter, and sends back as the output, a single simple class. This class, called HostInterface, contains just two parameters, a string (which I use to encapsulate all my strings and ints) and a byte() array (into which I stuff all my binaries)

So, whether a client is calling something simple like Ping() with just one string param, or something complicated like ResumeDownload() with 5 strings, 2 ints and a byte array, all of those parameters get encapsulated in my HostInterface class, the strings and ints into the one String parameters (as XML) and the bytes into the byte field.

When a request is received on the host side here:

  Function HostConnect(byval objInbound as HostInterface) as HostInterface

I unpack the string parameter in objInbound, changing the XML into an object, and I unpack the bytes and add them to the byte portion of the same object. Then I check the method name (ping or ResumeDownload) and process accordingly. The diagram below shows the basic idea - all functions operating through a single function that takes and sends the same simple classe as parameters. Thus, my interface never needs to change.

Brian
  • 3,653
  • 1
  • 22
  • 33
  • can u put the a sample example like what u said as a result things should be better clear to me. thanks – Thomas Jan 23 '14 at 12:09
  • this kind of problem can be handle by wcf routing? – Thomas Jan 23 '14 at 12:10
  • Interface changes can't be fixed with routing. Creating a single, stable, handles-all-cases endpoint interface is the approach I used. Sample code would be hard because there's a lot of it spread across multiple projects and classes, but I might be able to come up with something. – Brian Jan 23 '14 at 14:38
  • thanks a lots for your answer. it would be ver helpful & nice for me if u create small sample code for me the way u manage your situation. just there will be one contract with three method and client side code for consuming. thanks :) – Thomas Jan 24 '14 at 06:45
  • Thomas, sorry, I wish I could but I don't have time for that. But all you really need are three things: 1) a class that will take all the parameters from your web service function and pack them up into xml. 2) you need a basic class (like in the diagram) that takes a string and a byte. 3) You need to create a single endpoint that takes your basic class as its input param and returns the same basic class as out an output param - using same classes on both ends makes things easier. Good luck – Brian Jan 24 '14 at 07:34