简体   繁体   English

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

[英]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.之前我们有一个名为 PropertyUpdated 的事件,它是由聚合引发的。 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.现在这个 class 的模式已经改变,并且事件也被制作为抽象 class。 We now have more specific derived classes like TemplatePropertyUpdated, SystemPropertyUpdated, etc.我们现在有更具体的派生类,如 TemplatePropertyUpdated、SystemPropertyUpdated 等。

As you can see, if I load older aggregate events and try to hydrate the state, I'll get errors during deserialization.如您所见,如果我加载较旧的聚合事件并尝试对 state 进行水合,我将在反序列化过程中出错。 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.我们使用 BinaryFormatter 进行序列化和反序列化。 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?从这个旧事件创建动态 object 以便可以派生更新版本的最佳方法是什么?

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.所有对象都被转换为相应的序列化 object,然后再返回。

If there is a significant change in the object hierarchy you would rename the serialization object to something like MyObjectLegacy or MyObject_v0.如果 object 层次结构发生重大变化,您可以将序列化 object 重命名为 MyObjectLegacy 或 MyObject_v0。 The conversion code can then convert the old serialization object to whatever new object(s) you want to use.然后转换代码可以将旧的序列化 object 转换为您想要使用的任何新对象。 This helps keep serialization separated from the rest of the object model.这有助于将序列化与 object model 的 rest 分开。

If you lack a serialization layer I see few other options than keeping the old class around just so you can unpack it.如果您缺少序列化层,除了保留旧的 class 以便您可以打开它之外,我几乎没有其他选择。 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.您也许可以使用绑定重定向或其他东西来重命名 class,但根据我的经验,这有点脆弱。

I would encourage you to switch to something other than BinaryFormatter.我会鼓励你改用 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 .还有更好的选择,比如 protobuf.Net、Bson、json 等。看看比较 We had some problems when BinaryFormatter changed format between different.Net versions, not fun.当 BinaryFormatter 在不同的.Net 版本之间更改格式时,我们遇到了一些问题,不好玩。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM