4

If I need to go from this service contract:

[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IService1
{
   [OperationContract(Name = "AddCustomer")]
   bool AddCustomer(DTOCustomer1 customer);
}

to this:

[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IService1
{
   [OperationContract(Name = "AddCustomer")]
   bool AddCustomer(DTOCustomer2 customer);
}

and according to this good article: Versioning WCF I understand that when data contract is changed there is a need of defining a new vs of data contract in new namespace followed by defining a new vs of service contract in new namespace, after which a new endpoint should be added.

How exactly am I suppose to have this done. Is there an example anywhere? Could you write something based on my service contract shown above?

Thank you in advance!

RQDQ
  • 15,461
  • 2
  • 32
  • 59
Learner
  • 3,297
  • 4
  • 37
  • 62
  • May be you can also think to handle WCF versioning by including in the URL link of Services the version number. And within WCF Services project you can use different folders for each version as well. – NoWar Jan 10 '12 at 19:02
  • @Dmitry: I find this interesting. Could you point me out any links related to this? Thank you – Learner Jan 11 '12 at 08:32
  • 1
    I don't remember where I found this approach... But there are some links here http://stackoverflow.com/questions/931109/strategies-for-updating-or-versioning-web-services and http://stackoverflow.com/questions/2306181/pros-and-cons-of-web-services-versioning-strategies – NoWar Jan 11 '12 at 13:44

2 Answers2

4

According to the linked article you should do something like:

[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IServiceNew : IService1
{
   [OperationContract(Name = "AddCustomerNew")]
   bool AddCustomer(DTOCustomer2 customer);
}

Then implement it in your service:

public class MyCurrentServiceImplementation : IServiceNew 
{...}

You will need to redeploy your service but existing clients should be able to continue to call the AddCustomer operation, and new clients can call the AddCustomerNew operation.

tom redfern
  • 30,562
  • 14
  • 91
  • 126
  • Thanks a lot, is very much appreciated! Yes, I was waiting for something along these lines. The only thing remaining is to define a new endpoint for the new svc contract, right? – Learner Jan 11 '12 at 08:49
  • Yes you should expose the new service contract across a new endpoint - this will make the new operation available – tom redfern Jan 11 '12 at 08:53
  • if 'MyCurrentServiceImplementation' was before: 'MyCurrentServiceImplementation: IService1' will become now 'MyCurrentServiceImplementation: IServiceNew' right? – Learner Jan 11 '12 at 09:45
  • Let me try a simple test and will accept your answer... thanks a lot Hugh! – Learner Jan 11 '12 at 09:46
  • Hugh, your answer started with "according to the linked article"... Would you prefer another way? Is there a better practice? – Learner Jan 11 '12 at 14:45
  • This is the lowest cost way of doing it. However something about it seems a little hacky. In my mind the better way would be to offer a separate service with the new operation. – tom redfern Jan 11 '12 at 15:16
  • 'New separate service' meaning a new url, service contract and namespace with no inheritance between the 2 services? – Learner Jan 11 '12 at 15:22
  • Even a new host process. Yes the idea would be to decouple the two operations. Then they could be managed as separate concerns from a versionning perspective. – tom redfern Jan 11 '12 at 15:33
  • Ok, I see. Although I agree with having different services (new .svc files), maybe I would like to reuse some config stuff from the web.config which is one for all my services, since I keep all my services inside the same service app hosted in IIS. – Learner Jan 11 '12 at 15:41
  • 1
    To be completely honest, I don't think re-use of configuration would factor largely into any service composition-related decisions I had to make. – tom redfern Jan 11 '12 at 15:45
3

It's very important to note that the assumption you state in your post:

"when data contract is changed there is a need of defining a new vs of data contract in new namespace"

is not always true. See "Data Contract Versioning" on MSDN for a number of cases where a data contract change is non-breaking and may therefore require no action other than perhaps modifying the internal implementation of your service method to handle the presence/absence of certain data due to differences between data contract versions.

In this specific example I would question how two versions of a method called AddCustomer can vary so much in their intent that it justifies creating a new service interface. Without seeing your old and new data contracts I can't know for sure, but I'm guessing that the real issue here is that the method has evolved to accept additional customer information.

If that's true, then it's very much like the situation of optional arguments in a method call. WCF is designed to handle this scenario very nicely as a non-breaking change to the data contract. As long as you can follow the guidelines in "Best Practices: Data Contract Versioning" on MSDN, then calls supplying either the old or new version of the contract will be accepted just fine by your existing service interface. Your service method will get the data that is possible given the combination of the client and server data contracts.

I would keep my service interface coherent, simple, and clean (i.e. avoid doing things like IServiceNew) and instead just add to the data contract and modify the implementation of AddCustomer to adapt to the whatever data it receives.

BitMask777
  • 2,543
  • 26
  • 36