How to name multiple versioned ServiceContracts in the same WCF service?

When you have to introduce a breaking change in a ServiceContract, a best practice is to keep the old one and create a new one, and use some version identifier in the namespace.

If I understand this correctly, I should be able to do the following:

[ServiceContract(Namespace = "http://foo.com/2010/01/14")]
public interface IVersionedService
{
    [OperationContract]
    string WriteGreeting(Person person);
}

[ServiceContract(Name = "IVersionedService", Namespace = "http://foo.com/2010/02/21")]
public interface IVersionedService2
{
    [OperationContract(Name = "WriteGreeting")]
    Greeting WriteGreeting2(Person2 person);
}

With this I can create a service that supports both versions. This actually works, and it looks fine when testing from soapUI.

However, when I create a client in Visual Studio using "Add Service Reference", VS disregards the namespaces and simply sees two interfaces with the same name. In order to differentiate them, VS adds "1" to the name of one of them. I end up with proxies called

ServiceReference.VersionedServiceClient

and

ServiceReference.VersionedService1Client

Now it's not easy for anybody to see which is the newer version.

Should I give the interfaces different names? E.g

IVersionedService1
IVersionedService2

or

IVersionedService/2010/01/14
IVersionedService/2010/02/21

Doesn't this defeat the purpose of the namespace?

Should I put them in different service classes and get a unique URL for each version?

Answers


Well, typically, you would not have a service implementation that implements both the old and the new interface at the same time. Therefore, if a new client comes along and connects to your new service, it would only get the new interface and all is fine.

If you need to be able to offer up both interfaces, then yes - you need to do some "magic" to make this possible:

  • if you can, derive the new interface from the old. This works as long as you're only adding on new stuff. A new service implementation would then implement both the old-style interface, as well as the new

    public interface IVersionedService2 : IVersionService1
    {
        [OperationContract(Name = "WriteNewGreeting")]
        Greeting WriteNewGreeting(Person2 person);
    }
    

    So your service implementation would then have both a WriteGreeting as well as a WriteNewGreeting method - the new clients could connect to and use either, while older clients would still see their IVersionService1 interface and the "old" namespace, and thus be able to continue to call your service

  • if you cannot derive the new service from the old, create a completely new service, and expose it on a new endpoint, e.g. a new address or port. That way, existing clients can keep on calling the existing and well known service, while new ones can be directed to a separate service on a separate endpoint and things should be fine for them, too


Need Your Help

Convert array of strings into a string in Java

java arrays string

I want the Java code for converting an array of strings into an string.

No Activity found to handle Intent { act=android.intent.action.CALL dat=+123456789 pkg=com.android.phone }

android

The following code works fine when I click a button in an activity but gets an "No Activity found to handle Intent" error when a button in an fragment is clicked.