Search code examples
c#serialization.net-coreevent-sourcingbinaryformatter

How to deserialize a binary formatted object whose type got modified as an abstract class?


Our application uses event sourcing. Earlier we had an event called PropertyUpdated which was raised by an aggregate. This has been serialized and stored in our event store. Now the schema of this class has got changed and also the event has been made as an abstract class. We now have more specific derived classes like TemplatePropertyUpdated, SystemPropertyUpdated, etc.

As you can see, if I load older aggregate events and try to hydrate the state, I'll get errors during deserialization. I'm working on a tool to load older events and upgrade them as per the latest changes. We are using BinaryFormatter for Serialization and Deserialization. The older (non-abstract) event is now giving "cannot create an abstract class" exception during deserialization.

What is the best approach to create a dynamic object from this old event so that a newer version can be derived?


Solution

  • My preferred way to deal with things like this is to have a serialization-layer. All objects get converted to a corresponding serialization object, and back again.

    If there is a significant change in the object hierarchy you would rename the serialization object to something like MyObjectLegacy or MyObject_v0 . The conversion code can then convert the old serialization object to whatever new object(s) you want to use. This helps keep serialization separated from the rest of the object model.

    If you lack a serialization layer I see few other options than keeping the old class around just so you can unpack it. You might be able to use binding redirects or other stuff to be able to rename the class, but this is a bit fragile in my experience.

    I would encourage you to switch to something other than BinaryFormatter. It is slow, fragile, and produces relatively large files. There are much better alternatives, like protobuf.Net, Bson, json etc. Take a look at a comparison. We had some problems when BinaryFormatter changed format between different .Net versions, not fun.