Versioning Windows Communication Foundation Services
To show how to properly deal with versioning, I’ve created a versioning decision tree. It shows you what you will need to do to handle every case, and it also shows you the consequences of each versioning choice you might make.
The white diamonds are versioning decisions, decisions about how you might version a service. The squares represent actions you will need to take as a result of your versioning choices. Squares that are green represent non-breaking changes. Squares that are red represent breaking changes. Naturally, and this is one of the first versioning practices you can derive from the decision tree, you want to avoid decisions that lead to breaking changes, that lead to red squares.
So let us follow the decision tree. You have a service, and now you need to modify it.
Can you meet your objectives in modifying the service by adding a new operation to the service? If so, then that is readily accomplished through service contract inheritance. Simply define a new service contract that derives from the service contract of the existing service, add the new operations to the new service contract, and then have your service type, the class that implements the existing service contract, implement the new service contract instead of the old one. Update the definition of the service endpoint so that it refers to the new, derived service contract. Now existing clients, which will only know about the old service contract, can have the operations that they already knew executed at the original endpoint, and new clients, which know about the enhanced service contract, can have the additional operations executed at the same endpoint.
[ServiceContract]
public interface IMyServiceContract
{
[OperationContract(IsOneWay=true)]
public void MyMethod(MyDataContract input);
}
[ServiceContract]
public interface IMyAugmentedServiceContract: IMyServiceContract
{
[OperationContract(IsOneWay=true)]
public void MyNewMethod(MyOtherDataContract input);
}
public class MyOriginalServiceType: IAugmentedServiceContract
If your requirements for modifying the service cannot be met by adding new operations to the service, do you then have to change an existing operation? If so, then how exactly do you need to change it?
Do you need to change the structure of the data passed to the service by its clients? If so, then you need to version a data contract.
How do you need to modify the data contract? If it is simply a matter of incorporating more data into the data contract, then that is easy to do, simply by adding new, optional members to the data contract.
It is a good practice to implement the IExtensibleDataObject interface on all data contracts, so that if you have to process an instance of an enhanced version of the data contract, that includes members of which you are not aware, then the data for those additional members can pass through your code without being lost. Implementing IExtensibleDataObject provides the data contract serializer with a place to store the additional data on the way into your code, from which the data can be retrieved again on the way out.
[DataContract]
public class MyDataContract: IExtensibleDataObject
{
[DataMember(IsRequired=true)]
public XType MyOriginalMember;
[DataMember(IsRequired=false)]
public XType MyNewMember;
private ExtensionDataObject extensionData;
public ExtensionDataObject ExtensionData
{
get
{
return this.extensionData;
}
set
{
this.extensionData = value;
}
}
}
When you are forced to make other changes to a data contract besides simply adding members, then you must take the steps shown in the decision tree.
- You must define a new version of the data contract in a new namespace, and the naming of your namespaces should reflect your version numbers.
- You must define a new version of your service contract with an operation that uses the new version of the data contract. Once again, the namespace of the service contract should identify the version.
- You must create a new endpoint where the new service contract is exposed.
- Finally, you must decide whether to retire the existing endpoint.
If the requirements for the new version of your service require you to make any other kinds of changes to an operation defined in a service contract, or delete any operations from a service contract, or change the bindings of a service, then these are the steps you must take:
- You must define a new version of your service contract with an operation that uses the new version of the data contract, with the namespace identifying the version.
- you must create a new endpoint where the new service contract is exposed.
- You must decide whether to retire the existing endpoint.
Only the decision to retire an existing endpoint constitutes a breaking change. To make it easier to retire endpoints, you should include a default operation for every service contract that you ever define, and you should specify that operation can throw a fault indicating that the endpoint has been retired. The information provided with the fault can direct the client to the metadata for the replacement endpoints.
[DataContract]
public class RetiredEndpointFault
{
[DataMember]
public string NewEndpointMetadata
}
[ServiceContract]
public interface IMyServiceContract
{
[OperationContract(IsOneWay=true)]
public void MyMethod(MyDataContract input);
[FaultContract(typeof(RetiredEndpointFault))]
[OperationContract(Action=“*”,ReplyAction=“*”)]
public Message MyDefaultMethod(Message input);
}
Leveraging the default operation and fault contract facilities of the Windows Communication Foundation in this way yields the same benefits with far less effort than the facade service approach that is recommended here and here.
Comments
Anonymous
July 23, 2006
Craig has a post here on WCF that discusses the option you have for version a WCF service.Anonymous
July 25, 2006
Cannot view the image?Anonymous
August 17, 2006
Jeg havde den fornøjelse her til aften, at få lov til at præsentere nyhederne i .NET 3.0 for en forsmaling...Anonymous
November 06, 2006
An architecture to retain unknown extensions — more advice from Dave Orchard on versioning with XML Versioning Web Services with WCF — nice write-up by Craig McMurtry Scaling the Tufte Effect — Jon Udell plays with Sparklines *aptana.tvAnonymous
December 11, 2006
Craig McMurtry has some great notes on the various decisions involved in changing a web services interface to a new version. http://blogs.msdn.com/craigmcmurtry/archive/2006/07/23/676104.aspx As well as a decision tree to walk through the choices, heAnonymous
February 13, 2007
Patrik Löwendahl på Cornerstone är MVP med fokus på C#. Han skriver ett absolut intressant inlägg i SOA-debattenAnonymous
May 07, 2007
Egy végtelenül hosszú linklista következik itt...Anonymous
May 07, 2007
¾ Step 1 – Read Principles of Service Design: Patterns and Anti-Patterns for an overview of SOA basicsAnonymous
September 24, 2007
PingBack from http://msdnrss.thecoderblogs.com/2007/09/24/guia-de-auto-estudio-de-wcf-windows-communication-foundation/Anonymous
November 07, 2007
I ran across this post tonight from Craig McMurtry (author of Microsoft Windows Communication Foundations:Anonymous
November 07, 2007
Courtesy of LOBOMINATOR from MSDN forums....more links and posts on service versioning... :), plus i'mAnonymous
November 26, 2007
PingBack from http://feeds.maxblog.eu/item_440379.htmlAnonymous
July 17, 2008
¾ Step 1 – Read Principles of Service Design: Patterns and Anti-Patterns for an overview of SOA basicsAnonymous
July 17, 2008
¾ Step 1 – Read Principles of Service Design: Patterns and Anti-Patterns for an overviewAnonymous
August 25, 2008
I am constantly surprised when speaking with people how few have heard of or use the “Service Interface”Anonymous
October 13, 2008
More web service versioning infoAnonymous
June 08, 2009
PingBack from http://toenailfungusite.info/story.php?id=4106