Friday, January 25, 2008

Binary Serialization and versioning

Serialization is really a powerful feature. My personal favorite is the binary kind, but it has a limit. If you try to deserialize an object who's class has changed since it was serialized chances are that you will most likely get an exception. I have tried it on several occasions, but I never got around to research the problem, before now.

There are three possible solutions to the problem as far as I see it, all of them having one thing in common: they all require that the classes that are to be serialized implements ISerializable.

It does not take that much effort to implement ISerializable. There are only one method in the interface that the compiler requires you to implement which is GetObjectData but you will also have to implement the constructor that is used for deserialization. Since interfaces cannot contain constructors you will have to remember this yourself, or you will be gently hinted at runtime when trying to deserialize an object that does not have that constructor.

Now the trick is that inside the constructor you must implement a check that makes sure that the values that must be deserialized exists in the SerializationInfo object. I call it a trick because I am not able to find a beautiful way of checking if the values are available. Currently I see three not that beautiful ways to do that check:

1) try and catch
You surround each of the value readings with a try/catch. So in case that the value is not available you catch the exception and set a default value.

2) Assembly name
You read the AssemblyName property from the SerializationInfo object. This string contains the Version of the assembly when the object was serialized. If you remember to update this version number when compiling your assemblies you can use it to evaluate how to proceed reading the values.

3) Reflection
The SerializationInfo class has a private (surprised?) method named FindElement which returns the index of the element if it exists and -1 if the element does not exist. I know you really cannot use the index for anything but the -1 is the one you would want to check for. If the method return -1 you know that it will do no good to try to get the value.

Now that wasn't so bad, but hopefully in the future we will get a public method that can tell us if the element exists in the SerializationInfo object.

$0.02

Read more!