Normally, when I have a class I want to allow to serialize, I take full control over that serialization by setting the Serializable attribute as well as implementing the ISerializable interface. With BASeBlock, for example, that is the route I’ve taken to write out the LevelSets, HighScores, and other data (putting them through a DeflateStream, mind you).
Recently I took to trying my hand at a Windows 8 App. The main thing that prevented me from doing this when I first got Visual Studio 2012 installed on my laptop running Win8 was simply that I couldn’t think of an application to make that wasn’t of a ridiculous scope. I thought of one, however- a simple time tracker. Basically you would have separate “stopwatches” which you can start or stop as needed.
Of course, in creating this App, I used the Visual Studio 2012 template for Windows 8 Store Applications. As I added classes, I got to thinking I would probably need to serialize and deserialize information on resume and suspend, So I did what I normally do- tagged the class with the Serializable attribute, and tried to implement ISerializable.
Unfortunately I learned that the ISerializable interface (and other classes such as BinaryFormatter) were not supported for win8 Store Applications. So I turned to the DataContractSerializer, which works differently, but works.
What is my point? I’m not sure. But Serialization in .NET is rather fractured. Ideally, you should be able to implement ISerializable in a class and use any number of formatter classes to serialize and deserialize an Object graph. The reality is that you only have a small handful of IFormatter implementations, some of which require information that you don’t always have before you even construct them, then you have the XML Serialization components, which also have some interesting issues particularly with regard to classes that implement the IDeserializationCallback interface. The annoying bit is even where they have things in common, there are differences. For example, you have to use various attributes to specify different options for your classes members for certain IFormatter implementations. I would argue that this sort of defeats the entire point of having those interfaces to begin with, which is to separate implementation details from how they are used; in this case, the fact that you want to serialize to XML or binary or SOAP, or what-have-you should not matter. But, sadly, it does.
“So make it yourself” you say. Well, that’s reasonable on it’s surface, but that would just add yet another Serialization framework to the ecosystem. Even so, though, I was considering making one, if only for myself, but I haven’t decided if it would be worth the effort.
The next best thing is creating custom IFormatter implementations. These are not impossible but they have quite a few issues in the form of having the honour the various interfaces like IDeserializationCallback as well as instantiating types, and so on and so forth, and it’s only good form to raise appropriate exceptions rather than let some exception unwind the stack to a catch clause that has no idea how to handle it.