Against Serialization with XmlSerialization
There’s a terrible monster in .NET’s closest, and its name is XmlSerialization. I love serialization to XML (or whatever your node-based text format of choice is), and I love XML in .NET and C#, but XmlSerialization is a horror. Let’s look at the requirements for XML serialization with the classes in System.Xml.XmlSerialization:
- XML serialization serializes only the public fields and read/write property values of an object.
- XML serialization requires a default constructor to be declared in the class that is to be serialized.
What is serialization useful for?
- Persist the state of objects.
- Modify XML documents without using the DOM.
- Pass an object across applications and domains.
- Pass an object anywhere as a string.
That is stuff that is not just useful, it is essential. The problems with XmlSerialization are the constraints it puts on class design. They are deal-breakers for me- any technology that places such requirements on class design as XmlSerialization is terrible in my eyes. If I wrote some technology that had the requirements of XmlSerialization, and distributed it, I’d get harangued, and rightly so (there are complaints against nHibernate because every property must be virtual, this is infinitely worse in comparison). So what are the constraints/problems?
Note: I’m going to use the word ‘entity’ for a class that should only have one instance per-identity. There should only ever be one instance of Widget with the ID ‘50935’ which other objects refer to.
Only public properties with public getters and settings are serialized.
This is the first of two huge slaps to good class design. One goal of designing good code is exposing the minimal public interface possible. Many classes only need a few public property setters, but this requires making them all public. Also, you cannot persist data that only exists in protected properties. Finally, you need to err on the side of making everything public, rather than choosing the most protected access possible from the start. These requirements are in direct contradiction to the ‘do not expose the internals of your class’- anyone consuming your class needs to have full access to all persistent components.
Serializable classes require a parameterless constructor.
Yikes. Few classes I write have a parameterless constructor, especially ones that need to persist. Entities need some sort of identification that is usually part of the constructor- serializable classes can have many instances of the same data.
The above two points are the most severe, since they fly in of both entities, which should have a single instance, and immutable classes, which have no public setters.
Little control over how objects serialize.
This is important. If you have a property that holds a reference to a class, it will only serialize if that class is serializable. And if it is serializable, but it is an entity, it will serialize a new instance. Interfaces will not serialize AT ALL.
Overcoming constraints is complex!
You are able to program around most of these problems. But if you’re going to do that, you need to really examine why you are using XmlSerialization. I know from experience with multiple teams here that most XML serialization with XmlSerialization does what is much better handled through custom serialization routines. I’d always first try to use custom serialization, and only use the built-in XmlSerialization is absolutely necessary, namely when doing much more advanced things with XML, such as, assuring certain typesafeties, namespaces, standard compliance, etc, or for the representation of relatively simple data objects, such as user preferences. But I see it most often used for simple data persistence or passing of data between .NET applications, and in those cases it is never my method of choice.
So that’s just a fraction of my case against XmlSerialization. You can find many more problems on the internet, but you’ll have to look into it, because they are rarely phrased as serious problems- it is one of those technologies that unassuming cargo-cultists gravitate towards. They have little understanding of the intended usage, power, costs, and other options, but they use it anyway. In a future post, I’ll go over strategies for custom serialization and how they address the problems associated with XmlSerialization.