On a project I was working on, we were in the need for serialization en mass. A lot of classes had to be serializable. Following are the requirements, the stages towards a solution, and a proposed solution.
- It must be simple for the application programmer.
- The serialization output should be XML.
- Future changes in the serialization code must not involve making changes to the client code. E.g., we may have to encrypt the serialized object representation.
Using the code
Since this was my first date with serialization, I naturally went Googling to get a feeling for who I'm dating. It quickly seemed that serialization wasn't that hard. Many people suggested using the following wherever you need to serialize:
Dim serializedObj As String
Dim serializer As New XmlSerializer(Me.GetType)
Dim writer As New StringWriter
serializedObj = writer.ToString()
Not so bad. You decorate your class with the
<SERIALIZABLE()> attribute, and maybe hide a few public properties with
XmlIgnore, and there you go. It was immediately ruled out to have the client code contain this code in every class. So what about a utility method that will serialize/deserialize an object? There are a few challenges here. The utility function must be able to handle any type of object. Until .NET 2.0, the answer would probably have been something along these lines:
Public Shared Function Serialize(obj as Object) As String
That looks OK. Let's have a look at the
Deserialize method as well, and see if there are any surprises hiding there. In order to deserialize, we need another piece of information that we had when serializing. We need to know what type to deserialize to. The following signature should give us enough information to get the job done.
Public Shared Function Deserialize(xml As String, _
obj As Object) As Object
The client code would then look something like:
Dim instance1 As New TestClass
Dim serializedInstance As String = _
Dim instance2 As New TestClass
instance2 = CType(SharedLib.DeSerialize(serializedInstance, _
At this point, I was in doubt. Should I stop here and accept something that I didn't feel very good about, or should I spend some more time to try to find a better solution? I had two problems with the above code. The client code was not intuitive enough, and there was still too much code needed to get the job done. From an object oriented perspective, I would much more like to have the methods on the class itself. I decided to look for something else. I hear you shout Generics, so here it comes, but with a twist. We'll leave the concept of utility functions all together. In a normal object model, you have objects that contain state and do actions. Most of us don't write
helperLib.Drive(myCar), but rather
myCar.Drive(). How can we apply that to the serialization problem at hand?
Let's first look at how we want the calling code to look like, and then on how to implement our serialization to match that.
Dim instance1 As New TestClass
Dim serializedInstance As String = instance1.Serialize()
Dim instance2 As TestClass1
instance2 = TestClass1.Deserialize(serializedInstance)
That's what I want the calling code to look like. Just to make things even between VB.NET and C#, I'll do the remaining part in C#. We want to add a
Serialize() and a
Deserialize() method to any class that needs to be serialized. In order to minimize the coding effort of the classes that will use this functionality in, we will write a generic base class with the implementation of the two methods.
Here is the base class implementation:
public abstract class ContractBase<T>
public string Serialize()
XmlSerializer serializer = new XmlSerializer(this.GetType());
using (StringWriter stream = new StringWriter())
public static T Deserialize(string xml)
throw new ArgumentNullException("xml");
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader stream = new StringReader(xml))
catch (Exception ex)
throw new InvalidOperationException("Failed to " +
"create object from xml string", ex);
Here is a sample class, using the serialization base class we just wrote:
public class TestClass : ContractBase< TestClass >
private string m_firstName;
public string FirstName
if (m_firstName == value)
m_firstName = value;
Note that the
TestClass inherits from a generic base class, passing in its own type as the generic type.
The calling code now looks like what we wanted.
TestClass instance1 = new TestClass();
string serializedInstance = instance1.Serialize();
instance2 = TestClass.Deserialize(serializedInstance);
See a better solution? Please let me know.
You can also visit my blog.