c# - 如何反序列化其类型被修改为抽象类的二进制格式对象?
问题描述
我们的应用程序使用事件溯源。之前我们有一个名为 PropertyUpdated 的事件,它是由聚合引发的。这已被序列化并存储在我们的事件存储中。现在这个类的模式已经改变了,事件也被做成了一个抽象类。我们现在有更具体的派生类,如 TemplatePropertyUpdated、SystemPropertyUpdated 等。
如您所见,如果我加载较旧的聚合事件并尝试对状态进行水合,我会在反序列化过程中出错。我正在开发一种工具来加载旧事件并根据最新更改对其进行升级。我们使用 BinaryFormatter 进行序列化和反序列化。旧的(非抽象)事件现在在反序列化期间给出“无法创建抽象类”异常。
从这个旧事件创建动态对象以便派生更新版本的最佳方法是什么?
解决方案
我处理此类事情的首选方法是使用序列化层。所有对象都转换为相应的序列化对象,然后再返回。
如果对象层次结构发生重大变化,您可以将序列化对象重命名为 MyObjectLegacy 或 MyObject_v0 之类的名称。然后,转换代码可以将旧的序列化对象转换为您想要使用的任何新对象。这有助于将序列化与对象模型的其余部分分开。
如果您缺少序列化层,除了保留旧类以便您可以解压它之外,我几乎没有其他选择。您也许可以使用绑定重定向或其他东西来重命名该类,但根据我的经验,这有点脆弱。
我会鼓励你改用 BinaryFormatter 以外的东西。它很慢、很脆弱,并且会产生相对较大的文件。还有很多更好的选择,比如 protobuf.Net、Bson、json 等。看看比较。当 BinaryFormatter 在不同的 .Net 版本之间更改格式时,我们遇到了一些问题,不好玩。
推荐阅读
- sql - mssql:为所有行添加具有相同值的列到搜索结果
- c# - 如何将 EPPlus 中创建的图表导出到图像文件
- asp.net-mvc - Using Business Object As Model is not working?
- python - OpenCV 的这个功能哪里去了?
- firebase - JS函数在promise解析之前返回值
- javascript - 在Interval React.js中乘以数字时如何获得索引0
- javascript - 悬停在父元素上但不影响子元素
- angular - 在 Angular 7 中实现 bcrypt
- c# - 无法使用 EF Code First 以 1 : 1 映射将记录保存到数据库
- firewalld - 单位 firewalld.service 找不到