Backwards compatibility in .NET with BinaryFormatter

隐身守侯 提交于 2019-11-30 09:08:13

Tough one. I would dump binary and use XML serialization (easier to manage, tolerant to changes that are not too extreme - like adding / removing fields). In more extreme cases it is easier to write a transform (xslt perhaps) from one version to another and keep the classes clean. If opacity and small disk footprint are a requirement you can try to compress the data before writing to disk.

We got the same problem in our application with storing user profile data (grid column arrangement, filter settings ...).

In our case the problem was the AssemblyVersion.

For this problem i create a SerializationBinder which reads the actual assembly version of the assemblies (all assemblies get a new version number on new deployment) with Assembly.GetExecutingAssembly().GetName().Version.

In the overriden method BindToType the type info is created with the new assembly version.

The deserialization is implemented 'by hand', that means

  • Deserialize via normal BinaryFormatter
  • get all fields which have to be deserialized (annotated with own attribute)
  • fill object with data from the deserialized object

Works with all our data and since three or four releases.

This is a really old question, but it needs an up-to-date answer anyway. Today, in 2019: I would suggest anyone reading this to seriously consider using Protobuf instead of BinaryFormatter. It has most of the advantages of a binary format (which it is) but fewer of its disadvantages.

  • It works between different languages and technology stacks with ease (Java, .NET, C++, Go, Python)
  • It has a well-thought-through strategy for handling breaking changes (adding/removing fields, etc) in a way that means it's much easier for "version x" of your software to handle "version y"-generated data and the other way around. Yes, this is actually true: an older version of your app will be able to handle data serialized with a newer version of the Protobuf .proto interface definition. (Non-present fields will simply be ignored when deserializing.)

    By comparison, when running a newer versions of the code and deserializing old data, "not-present" fields in the data will be set to their type-specific default value. In that sense, handling old data is not "fully automatic" in that sense, but still a lot simpler than when using the default binary serialization libraries included with platforms like Java and .NET.

If you prefer a non-binary format, JSON is often a suitable choice. For RPC and such scenarios, Protobuf is better though and is even officially being mentioned/endorsed by Microsoft nowadays: Introduction to gRPC on ASP.NET Core. (gRPC is a technology stack built on top of Protobuf)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!