I've been sub-contracted to do work on an in-house API which is implemented using WCF.
While looking through the API which I need to interact with and modify, I came across a new concept which apparently, unbeknowest to me, is a recomendation that all WCF message contracts should implement.
That is the concept is of the implementation that your message contracts should implement IExtensiibleData, which exposes the need to implement an ExtensionDataObject type member on your contracts.
Some thing like this (taken from https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.extensiondataobject?view=netframework-4.6.2):
[DataContract(
Name = "Person",
Namespace = "http://www.cohowinery.com/employees")]
class Person : IExtensibleDataObject
{
// To implement the IExtensibleDataObject interface,
// you must implement the ExtensionData property. The property
// holds data from future versions of the class for backward
// compatibility.
private ExtensionDataObject extensionDataObject_value;
public ExtensionDataObject ExtensionData
{
get
{
return extensionDataObject_value;
}
set
{
extensionDataObject_value = value;
}
}
[DataMember]
public string Name;
}
While looking through this API and looking at modify the API internally, specifically to extend it to do additional work over and above what it routinely does. The need to ask a client of this API to somehow identify that when it calls any of the APIs methods, something slightly different should occurs for these clients.
So the problem of having this API to identify that its received a 'special' request from one such client, and do something exceptional in that case, where otherwise any other such request it would carry out default operation.
The idea of somehow sending as part of the request a means to identify that the request comes from one of these exceptional clients was the first thing to try and solve. But how to do somehow encode this intend into any incoming request without changing that requests structure/format/protocol such that older clients who know not of a change to that format/protocol(if we decide to to that) will still succeed in sending their now-older version of that format/protocol. One might change the request message format to now include an additional field that identifies an exception al request from any other where perhaps that field was not used or set.
The server would check this field in the message format and respond appropriately. Again, if an older client sends a older message format without this extra field, the server who expects that format to have this additional field will refuse to accept the message - as its now different.
This is what IExtensionData and ExtendionData solves by allowing newer as well as older message formats to both be accepted by the server, regardless of the changes that have occurred to the format moving forward. I like this.
Old formats will get accepted (without their extra info in them) while newer ones with their newer fields will also be accepted.
The server now can be changed to check what fields are and aren't available and act accordingly - perhaps executing different code paths based on what is or is not available in the incoming message format.
I'll go through how this is practically achieved by needing a new client who's definition of the original contract has now changed. So now it and the server agree on the contact but the server and older clients still need to be able to process and send older formats respectively too.
I'll show you how this works.
TBC