二进制对象图形序列序列、图形、对象

2023-09-03 16:47:19 作者:浅夜丶深悠眷念╰

我在寻找建议序列化在.NET应用程序。该应用程序是一个桌面/胖客户端应用程序和系列化重新presents持久化的文档格式。对于串行的要求

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

必须允许串行化领域,不仅是公共属性。 在不能要求参数构造函数。 必须处理一般对象图,即不仅DAG,但共享/双向引用。 必须与框架类(如序列化字典)。

目前,我们使用它处理所有上述的相当不错,但尺寸/性能和版本宽容是一个问题的BinaryFormatter。我们使用[OnDeserialized /和]属性来提供兼容性,但是它不允许大的重构(比如命名空间的变化)而无需复杂的用替代等。

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.

这是理想的解决方案将是一个下拉更换为BinaryFormatter的,以我们现有[非序列化]注释等工作,但性能更好,并产生一个格式,体积更小,更易于维护。

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.

我已经看过了不同的protobuf的实现,尽管它似乎可以通用序列化对象图/枚举/结构的这些天,它不会出现琐碎了很多框架的集合类型等的序列化一个复杂的图形也,即使我们可以把它与领域,而不是属性我知道它仍然意味着必须参数构造函数和protobuf的添加注释的所有类(域名为约1000班)的工作。

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).

因此​​,问题:

是否有任何另类二进制格式化,提供一个有据可查的格式,有更好的表现? 是协议缓冲区以往任何时候都适合坚持大将军的对象图,包括框架类型?

推荐答案

协议缓冲区的的格式的具有对象图没有官方的支持,但protobuf网的没有的规定这一点,满足您的其他要求。要取分依次为:

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:

必须允许串行化领域,没有公共属性仅

当然, protobuf网能做到这一点的公立和非公立领域;告诉它在任何运行时的字段或通过属性

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

在不能要求参数构造函数。

这是V2可用 - 再次,你可以告诉它跳过构造器在运行时,或者通过属性( SkipConstructor = TRUE 的合同)

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

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

当然,标记 AsReference = TRUE 的成员

必须与框架类(如序列化字典)。

标准列表和字典做工精细; 然而的,我有一个优秀的变更请求支持 AsReference 的在的一本字典。意思是,词典<字符串,富> 不会的现在的运行图$ C $下,但我也许可以找到一些时间来看看这是否是造成你显著疼痛

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

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

序列化回调完全支持

,但不允许大型重构(比如命名空间的变化)而无需复杂的用替代等。

命名空间等根本不是有趣的protobuf网(除非您使用的是 DynamicType 选项)

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

在它仍然意味着必须参数构造函数和protobuf的添加注释的所有类

不一定;如果可以的保证的,你会不会改变字段名,你可以要求它在内部推断场数 - 最终在V2的所有可以在指定运行时间,所以你可以经常编写的软件运行在应用程序启动和使用反射来配置系统,一个小的配置循环。然后,你就不需要更改现有的code的所有的。

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.