如何反序列化类型被修改为抽象 class 的二进制格式化对象?

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

我们的应用程序使用事件源。早些时候我们有一个名为 PropertyUpdated 的事件,它是由聚合引发的。这已经被序列化并存储在我们的事件存储中。现在这个 class 的模式已经改变,并且事件也被制作成一个抽象的 class。我们现在有更具体的派生 classes,例如 TemplatePropertyUpdated、SystemPropertyUpdated 等

如您所见,如果我加载较旧的聚合事件并尝试混合状态,我将在反序列化过程中出错。我正在开发一种工具来加载旧事件并根据最新更改升级它们。我们正在使用 BinaryFormatter 进行序列化和反序列化。旧的(非抽象)事件现在在反序列化期间给出“无法创建抽象 class”异常。

从这个旧事件创建动态对象以便派生新版本的最佳方法是什么?

我处理此类事情的首选方法是使用序列化层。所有对象都转换为相应的序列化对象,然后再转换回来。

如果对象层次结构发生重大变化,您可以将序列化对象重命名为 MyObjectLegacy 或 MyObject_v0 之类的名称。然后,转换代码可以将旧的序列化对象转换为您要使用的任何新对象。这有助于将序列化与对象模型的其余部分分开。

如果您缺少序列化层,除了保留旧的 class 以便您可以解压之外,我看不到其他选择。您也许可以使用绑定重定向或其他东西来重命名 class,但根据我的经验,这有点脆弱。

我鼓励您改用 BinaryFormatter 以外的东西。它速度慢、脆弱,并且会生成相对较大的文件。有更好的选择,比如 protobuf.Net、Bson、json 等。看看 comparison。当 BinaryFormatter 在不同的 .Net 版本之间改变格式时,我们遇到了一些问题,不好玩。