6

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

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

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

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

我已经查看了不同的 protobuf 实现,尽管这些天似乎可以序列化一般对象图/枚举/结构,但序列化具有许多框架集合类型等的复杂图似乎并不容易。此外,即使我们可以让它与字段而不是属性一起工作,我理解这仍然意味着必须向所有类添加无参数构造函数和 protobuf 注释(域大约有 1000 个类)。

所以问题:

  • 是否有任何“替代”二进制格式化程序,提供有据可查的格式,性能更好?
  • 协议缓冲区是否适合持久化包括框架类型在内的大型通用对象图?
4

2 回答 2

5

协议缓冲区作为一种格式没有对对象图的官方支持,但 protobuf-net确实提供了这一点,并满足您的其他要求。依次取分:

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

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

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

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

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

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

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

标准列表和字典工作正常;但是,我有一个出色的更改请求需要AsReference 字典中提供支持。意思是,目前Dictionary<string, Foo>不会为 运行图形代码,但如果它给你带来很大的痛苦,我可能会花一些时间来看看这个Foo

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

完全支持序列化回调

  • 但它不允许在没有复杂使用代理等的情况下进行大型重构(例如命名空间更改)。

命名空间等对 protobuf-net 一点也不感兴趣(除非您使用这些DynamicType选项)

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

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

于 2011-08-03T09:04:56.087 回答
0

试试db4o,它不是真正的序列化程序,但据我所知,它满足您的要求(复杂类型、深度图、继承?、字典等),您无需更改对象上的任何内容,而且 API 非常便于使用。

它支持模式版本控制/合并。

于 2011-08-03T09:01:03.853 回答