c# - 二进制对象图序列化

标签 c# .net serialization protocol-buffers binaryformatter

我正在寻找有关 .net 应用程序序列化的建议。该应用程序是桌面/胖客户端应用程序,序列化表示持久化的文档格式。序列化器的要求是

  • 必须允许序列化字段,而不仅仅是公共(public)属性。
  • 不得要求无参数构造函数。
  • 必须处理一般对象图,即不仅是 DAG,还有共享/双向引用。
  • 必须使用框架类(例如序列化字典)。

目前我们使用的 BinaryFormatter 可以很好地处理上述所有问题,但大小/性能和版本容错性是一个问题。我们使用 [OnDeserialized/ing] 属性来提供兼容性,但它不允许在不复杂地使用代理项等的情况下进行大型重构(比如 namespace 更改)。

理想的解决方案是 BinaryFormatter 的直接替代品,它可以与我们现有的 [NonSerialized] 注释等一起使用,但性能更好,并生成更小且更易于维护的格式。

我研究了不同的 protobuf 实现,尽管现在似乎可以序列化一般对象图/枚举/结构,但序列化具有许多框架集合类型等的复杂图似乎并不简单。另外,即使我们可以让它使用字段而不是属性,我理解它仍然意味着必须向所有类添加无参数构造函数和 protobuf 注释(该域​​大约有 1000 个类)。

所以问题:

  • 是否有任何“替代”二进制格式化程序提供了良好的记录格式,性能更好?
  • protocol buffers 是否适合持久化包括框架类型在内的大型通用对象图?

最佳答案

Protocol buffers 作为一种格式 没有对对象图的官方支持,但是 protobuf-net 确实提供了这个,并且满足了您的其他要求。依次取分:

  • 必须允许序列化字段,而不仅仅是公共(public)属性

当然; protobuf-net 可以为公共(public)和非公共(public)领域做到这一点;在运行时或通过属性告诉它有关字段的信息

  • 不得要求无参数构造函数。

这在“v2”中可用 - 同样,您可以告诉它在运行时或通过属性(契约(Contract)上的 SkipConstructor=true)跳过构造函数

  • 必须处理一般对象图,即不仅是 DAG,还有共享/双向引用。

当然;标记 AsReference=true在成员(member)上

  • 必须使用框架类(例如序列化字典)。

标准列表和字典工作正常; 但是,我有一个未完成的变更请求来支持AsReference 字典中。意思是,Dictionary<string, Foo> 目前不会为 Foo 运行图表代码, 但如果它给你带来了很大的痛苦,我可能会花点时间看看它

  • 我们使用 [OnDeserialized/ing] 属性来提供兼容性

完全支持序列化回调

  • 但它不允许在不复杂地使用代理项等的情况下进行大型重构(比如 namespace 更改)。

命名空间等对 protobuf-net 来说一点也不有趣(除非你使用 DynamicType 选项)

  • 这仍然意味着必须向所有类添加无参数构造函数和 protobuf 注释

不一定;如果您可以保证您不会更改字段名称,您可以要求它在内部推断字段编号 - 最终在“v2”中一切都可以在运行时,因此您通常可以编写一个在应用程序启动时运行的小配置循环,并使用反射来配置系统。那么您根本不需要更改现有代码。

关于c# - 二进制对象图序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6923891/

相关文章:

c# - LINQ to Entity Framework 多对多预加载问题

javascript - 通过http请求将列表从 Angular 传递到C#

c# - Dll 由未知公司签名?

c# - 发布参数始终为空

c# - 将 SID 字符串格式转换为字节数组

serialization - Django-rest-framework,序列化程序中的嵌套对象

java - 配置函数在 Kafka 序列化器/反序列化器中起什么作用?

c# - 如何设置Excel窗口的大小?

c# - 如何将透明光标渲染到保留 alpha channel 的位图?

javascript - 将 THIS 与 jquery 可排序序列化一起使用