二进制对象图序列化

发布于 2024-11-27 16:01:27 字数 691 浏览 0 评论 0原文

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

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

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

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

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

所以问题是:

  • 是否有任何“替代”二进制格式化程序,可以提供良好记录的格式,性能更好?
  • 协议缓冲区是否适合持久保存大型通用对象图(包括框架类型)?

I'm looking for advice on serialization in a .net app. The app is a desktop/thick client app and the serialization represents the persisted document format. The requirements for the serializer is

  • Must allow serializing fields, not public properties only.
  • Must not require parameterless constructors.
  • Must handle general object graphs, i.e. not only DAG but shared/bidirectional references.
  • Must work with framework classes (e.g. Serialize Dictionaries).

Currently we use the BinaryFormatter which handles all of the above quite well, but size/performance and version tolerance is an issue. We use the [OnDeserialized/ing] attributes to provide compatibility, but it does not allow for large refactorings (say a namespace change) without complex use of surrogates and so on.

An ideal solution would be a drop-in replacement for BinaryFormatter that works with our existing [NonSerialized] annotations etc., but performs better, and produces a format that is smaller and easier to maintain.

I have looked at the different protobuf implementations, and even though it seems possible to serialize general object graphs/enums/structs these days, it does not appear trivial to serialize a complex graph with a lot of framework collection types etc. Also, even if we could make it work with fields rather than properties I understand it would still mean having to add parameterless constructors and protobuf annotations to all classes (The domain is around 1000 classes).

So the questions:

  • Are there any "alternative" Binary formatters, that provide a well documented format, perform better?
  • Are protocol buffers ever suitable for persisting large general object graphs including framework types?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尤怨 2024-12-04 16:01:27

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

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

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

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

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

  • 必须处理一般对象图,即不仅是 DAG,而且是共享的/双向参考。

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

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

标准列表和字典工作正常; 但是,我有一个未完成的更改请求,以支持内部字典的AsReference。意思是,Dictionary当前不会运行 Foo 的图形代码,但我可能可以找一些时间来查看如果它给您带来很大的痛苦,

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

完全支持序列化回调

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

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

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

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

Protocol buffers as a format has no official support for object graphs, but protobuf-net does provide this, and meets your other requirements. To take the points in turn:

  • Must allow serializing fields, not public properties only

Sure; protobuf-net can do that for both public and non-public fields; tell it about the fields at either runtime or via attributes

  • Must not require parameterless constructors.

That is available in "v2" - again, you can tell it to skip the constructor at runtime or via attributes (SkipConstructor=true on the contract)

  • Must handle general object graphs, i.e. not only DAG but shared/bidirectional references.

Sure; mark AsReference=true on a member

  • Must work with framework classes (e.g. Serialize Dictionaries).

Standard lists and dictionaries work fine; however, I have an outstanding change request to support AsReference inside a dictionary. Meaning, Dictionary<string, Foo> won't currently run the graph code for Foo, but I can probably find a few moments to look at this if it is causing you significant pain

  • We use the [OnDeserialized/ing] attributes to provide compatibility

Serialization callbacks are fully supported

  • but it does not allow for large refactorings (say a namespace change) without complex use of surrogates and so on.

Namespaces etc are not at all interesting to protobuf-net (unless you are using the DynamicType options)

  • it would still mean having to add parameterless constructors and protobuf annotations to all classes

Not necessarily; if you can guarantee that you won't change the field names, you can ask it to infer the field numbers internally - and ultimately in "v2" everything can be specified at runtime, so you can often write a small configuration loop that runs at app-startup and uses reflection to configure the system. Then you do not need to change your existing code at all.

漫漫岁月 2024-12-04 16:01:27

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

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

Try db4o, it's not realy a serializer but as far as I can tell it meets your requirements (complex types, deep graph, inheritance?, dictionaries etc), you don't have to change anything on your objects, and the API is extremely easy to use.

It supports schema versioning/merging.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文