Background: For some reasons I chose certain architechture for storing binary representations of my objects
I had a base class
EventBase
Guid AggregateId
DateTime Created
int SequenceNo
My applications “events” inherited from this base class like
public class ProjectActivatedEvent : EventBase, ICustomBinarySerializable
{
public ProjectActivatedEvent(Guid aggid, bool active)
: base(aggid, DateTime.Now)
{
Active = active;
}
public bool Active { get; set; }
For storage of serialized data I used a SQL Server table (eventstore)
![CropperCapture[15]](http://aspcode.net/wp-content/uploads/2010/09/CropperCapture15.png)
and serialized using Greg Youngs fast serializer (ICustomBinarySerializable) since its really fast and effective
My serialization code looked like
public void WriteDataTo(SerializationWriter writer)
{
base.WriteDataToBase(writer);
writer.Write(Active);
}
public void SetDataFrom(SerializationReader reader)
{
base.SetDataFromBase(reader);
Active = reader.ReadBoolean();
}
Now I wanted to do a major rearchitecturing of my code.
For starters, get rid of EventBase and introduce a Interface IEvent instead which all events inherits from.
Second: Use protobuf-net instead.
Basically:
[ProtoContract]
public class ProjectActivatedEvent : IEvent
{
public ProjectActivatedEvent()
{
}
public ProjectActivatedEvent(Guid aggid, bool active)
{
AggregateId = aggid;
Created = DateTime.Now;
Active = active;
}
[ProtoMember(10)] public bool Active { get; set; }
//IEvent
[ProtoMember(1)] public Guid AggregateId { get; set; }
[ProtoMember(2)] public int SequenceNo { get; set; }
[ProtoMember(3)] public DateTime Created { get; set; }
//
}
And there I was. I had two branches of my sourcecode, one the old way, one with the new way. Tests shows everything is working ok.
How can I now convert the (1500000) existing records in table eventstore to the new format?
The solution was to introduce JSon into the equation. So (using my old branch) I coded a app which loops all (old style) events, possible since the old code branch knows how to deserialize them of course, and converts them to JSon. Storing them into a intermediate table.
Second: from the new code branch I simple coded a new app which deserialized the JSon (into my new classes), and stored them the
Protobuf way.
The beauty of JSon (de)serializer is that it simply works on field names. I did not change the names of my fields so
it was therefore possible to use it as a pretty effective intermediate storage.
It did take some time running these loops but at least it worked.
I hope to present some more articles on this (and related) matters but want to show you the the trick to make a generic
(de) serializer out of Json without the need to specify the type:
class Json
{
static JsonSerializerSettings jsonSerializerSettings =
new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
TypeNameHandling = TypeNameHandling.Objects
};
public static string Serialize(object theObject)
{
return JsonConvert.SerializeObject(theObject, Newtonsoft.Json.Formatting.Indented, jsonSerializerSettings);
}
public static TType Deserialize(string sInData)
{
return (TType)JsonConvert.DeserializeObject(sInData, typeof(TType), jsonSerializerSettings);
}
}
The secret is TypeNameHandling.Objects. This adds a “$type:<typename>” in front of the JSon when serializing and
therefore it is able to create such an object when deserializing.
I still do have a TType, can’t remember why, since I stole thew code from an old project I made years ago, but the
point is you can send in Object or a baseclass as type.
I deserialize my data like:
Eventing.IEvent ev2 = Json.Deserialize<Eventing.IEvent>(row["data"].ToString());
And serialization was like
Eventing.EventBase b = …
string sa = Json.Serialize(b);