Take this situation:
I have a person class with:
- First Name
- Last Name
- Age
When serialised, I get something like this:
FirstName: Eddie
LastName: de Bear
Age: 30
Now this so far does not cause any problems. It's designed to work like this. When a service receives this message, it knows exactly what it is dealing with.. A Person.. That's what the contract defines, that's what it gets and deals with.
Now, Imagine I now have a new class Employee which inherits from Person and adds a single attribute, EmployeeId.
Now, when this gets serialised, what do we see:
(This assumes that the new Employee class still has the same contract name etc..)
Now, if this was passed to a Service that expects a person, the service has a little heart attack. It has no idea what to do with the new attribute EmployeeId.. It's not part of the person class..
There are a number of solutions to this, such as Method Overloading. But one of the solutions I find the most interesting is the mechanism WCF uses for Contract Versioning. IExtensibleObject.
In the example above, you could easily implement IExtensibleObject on the original person class. IExtensibleObject basically provides a property bag for dumping extra information that is encountered at deserialisation time. This allows the service to continue to treat the Employee object as a person, without loosing the additional information added by the employee class.
A great article on the use of the IExtensibleObject interface can be found Here
2 comments:
My preferred option is this:
[DataContract]
public class Person : PersonUpdateRequest
[DataContract]
[KnownType(typeof(Person))]
public class PersonUpdateRequest
Rory,
Yes, this does work really well. What I believe the advantage of the IExtensibleObject is, is the fact that the property Extensions actually holds the additional information on the service side (the bits it couldn't de-serialise). This allows you to still access the "extra" information without changing your contract.
I believe this mechanism was actuall intended for versioning, not for nasty inheritance hacks.. And to be honest, I find I tend to design any inheritance out of my contracts to avoid the whole situation.. ;)
Post a Comment