Thursday, September 28, 2006

.NET Serialization: Custom Formatter, IFormatter

This spring I wrote about how to use cloning and serialization to implement an entity row-state mechanism. We used the BinaryFormatter in the 'clone' and 'is dirty' methods as web-services was the protocol between our tiers (XML serialization), and .NET remoting was not to be used (binary serialization).

Of course, this "absolute requirement" has now changed and using the BinaryFormatter and the NonSerialized attribute is no longer an option as all properties/fields must now be available through remoting. It was time for a custom formatter as the BinaryFormatter class is sealed/NotInheritable.

As the help topics on IFormatter contains only API level details, I though I should share this excellent documentation and working code with you: Serialization Formatters (published by Universität Karlsruhe).

The article also explains the little known ISerializationSurrogate mechanism; this allows you to provide your own serialization mechanism for specific classes/object types/value types, even when using one of the standard formatters. This is typically used to serialize classes that are not marked as [Serializable]. It can also be used to provide specific handling of null/nothing strings and for normalizing the serialization of decimal values. The former is a problem for the .IsDirty mechanism because a null/nothing string is different from a ""/String.Empty string, while the latter is a problem because the decimal value 1 might be different from the value 1.0 as the binary representation might change.

You might also find this Advanced Serialization MSDN article useful.

[UPDATE] Serializing object graphs that comprises inheritance requires some extra work. If you need to serialize inherited composite objects, the XmlInlcude(typeof(DerivedClass)) class attribute is the best solution when derived classes are know at compile-time. If you need to serialize "unkown" derived objects, the CodeProject XmlSerializer and 'not expected' Inherited Types article provides a really simple solution (the comments section includes a Generics NodeSerializer<T>).

Some of the MSDN help topics lacks working, real-life examples of how to implement an interface or abstract class; which is too bad and makes developers waste a lot of time in "the desert of desperation". I had the same problem last year looking for a working example of how to implement a SoapExtension. I wish Microsoft could do a litte more to help developers fall into "the pit of success".

No comments: