Question

i am new but reading some article on wcf i came to know that if i change the ServcieContrcat then i 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 few 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

one guy answered before for the same situation

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.

i appreciate his answer but really do not understand how to implement it. so if anyone go to this url How to change WCF service contract which does not effect client?

then knows what he said.

i am looking for small complete wcf service code which help me to visualize how to design service contract in such way that if we extend the functionality of service contract later then client who will consume my service will not face any problem.

and tell me other possible guide line to solve this situation. thanks

Was it helpful?

Solution

I think the suggestion of creating a generic endpoint is a bad idea. By creating a method that takes any sort of input, you've lost all the strong-typing benefit that WCF in C# gets you. You still have to do the hard work of dealing with old clients, but now you have to do it in application code by inspecting the data coming in and heuristically deciding which "version" it assumes. In my mind, it's similar to creating a single SQL database table with dozens of columns named id, data1, data2, data3, data4, etc., then storing all kinds of unrelated data in that one table.

If the contract changes you need to make are backwards-compatible, then you can add them to the contract in-place. Adding a new method is backwards-compatible, since it doesn't affect the availability of the existing methods.

If you need to make backwards-incompatible changes (such as removing a method or changing the parameters of an existing one), the easiest answer may be to create a new contract that lives at a new address. If version 1 of your contract is reached at http://example.com/v1/MyService, then version 2 is reached at http://example.com/v2/MyService.

To avoid duplicating a lot of code between classes where the contract didn't change much, the classes that implement the contracts might inherit from each other. One way to do this could be:

namespace V1
{
    [ServiceContract]
    public interface IService { ... }
    public class MyService : IService { ... }
}

namespace V2
{
    [ServiceContract]
    public interface INewService { ... }
    public class MyNewService : V1.MyService, INewService { ... }
}

Or you can use composition:

public class MyNewService : INewService
{
    private readonly V1.MyService v1service = new V1.MyService();

    public int SomeMethod()
    {
        return this.v1service.SomeMethod();
    }
}

This way, MyNewService implements all the functionality of MyService, but only the methods exposed by INewService will be available via WCF. Anybody who accesses your service via the v2 URL will get the new functionality. Clients who are using the old service will continue to use the v1 URL until they're ready to upgrade.

OTHER TIPS

If I understand your problem correctly then probably ChannelFactory class might come to your rescue (partially at least). The link here will help you get started.

Also you might want to use IExtensibleDataObject for forward compatibity. Check the link here for better understanding.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top