Serialization is a method to save objects from memory to the hard disk and deserialization is the way back from hard disk to memory. There are several implementations of serializers in .NET, ranging from simple XML to binary output. VVVV uses XML serialization based on the XElement type from System.Xml.Linq, which represents an XML tag.
For reasons of code clarity and human readability of the XML output we use our own serialization method, which is basically an interface with two methods:
public interface ISerializer { XElement Serialize(object value, Serializer serializer); object Deserialize(XElement data, Type type, Serializer serializer); }
As the type of the object to serialize/desrialize is most of the time known on compile time there is also a generic version of the interface which is commonly used:
public interface ISerializer<T> { XElement Serialize(T value, Serializer serializer); T Deserialize(XElement data, Type type, Serializer serializer); }
The second important part of our serialization method is a global Serializer object. This global serializer knows all registered specific serializers and it also uses the .Net binary serializer to serialize all .Net types which are serializable by default. It is passed to each Serialize/Deserialize method, so that the writer of a serializer can serialize/deserialize objects of other types that may already have a registered serializer. The global serializer has a few methods to register specific Serializers and to serialize/deserialize objects:
//register specific serializer public void Register<TSource, TDest>() where TDest : ISerializer public void RegisterGeneric<TSource, TDest>() where TDest : ISerializer<TSource> public void Register(Type sourceType, Type serializerType) //serialize public XElement Serialize(object value) //deserialize public T Deserialize<T>(XElement data, Type type) public T Deserialize<T>(XElement data) public object Deserialize(XElement data, Type type)
To write a De-/Serializer for a certain type, one has to implement one of the interfaces above. And then register the serializer. For example, lets write a serializer for a simple class Foo:
class Foo { public string Bar; public int Baz; public Foo(string bar, int baz) { this.Bar = bar; this.Baz = baz; } }
The serializer could look like this:
class FooSerializer : ISerializer<Foo> { public XElement Serialize(Foo value, Serializer serializer) { //create base tag var x = new XElement("FOO"); //add tags for the fields var xBar = new XElement("BAR"); var xBaz = new XElement("BAZ"); xBar.Value = value.Bar; //let the serializer handle the int field xBaz.Add(serializer.Serialize(value.Baz)); x.Add(xBar); x.Add(xBaz); return x; } public Foo Deserialize(XElement data, Type type, Serializer serializer) { var bar = data.Element("BAR").Value; //get the int field var baz = serializer.Deserialize<int>(data.Element("BAZ").Element("OBJECT")); return new Foo(bar, baz); } }
Then the serializer must be registered at the global serializer, where and when this happens is application specific. Its as simple as:
GlobalSerializer.RegisterGeneric<Foo, FooSerializer>();
Then the it can be used to serialize/deserialize a Foo object:
The resulting XML will lool like:
<FOO> <BAR>Hallo serializer</BAR> <BAZ> <OBJECT Type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">100</OBJECT> </BAZ> </FOO>
anonymous user login
~22h ago
~7d ago
~7d ago
~8d ago
~21d ago
~1mth ago
~1mth ago
~1mth ago
~1mth ago
~1mth ago