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.