简体   繁体   English

二进制对象图序列化

[英]Binary object graph serialization

I'm looking for advice on serialization in a .net app. 我正在寻找有关.net应用程序序列化的建议。 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, ie not only DAG but shared/bidirectional references. 必须处理一般对象图,即不仅是DAG而是共享/双向引用。
  • Must work with framework classes (eg Serialize Dictionaries). 必须使用框架类(例如Serialize Dictionaries)。

Currently we use the BinaryFormatter which handles all of the above quite well, but size/performance and version tolerance is an issue. 目前我们使用BinaryFormatter来处理上述所有问题,但是尺寸/性能和版本容差是个问题。 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. 我们使用[OnDeserialized / ing]属性来提供兼容性,但它不允许大型重构(比如命名空间更改)而不需要复杂使用代理等等。

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

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实现,尽管现在似乎可以序列化一般对象图/枚举/结构,但是使用大量框架集类型等序列化复杂图形似乎并不容易。而且,即使我们可以使用字段而不是属性我理解它仍然意味着必须向所有类添加无参数构造函数和protobuf注释(域约为1000个类)。

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? 协议缓冲区是否适合持久化大型通用对象图,包括框架类型?

Protocol buffers as a format has no official support for object graphs, but protobuf-net does provide this, and meets your other requirements. 协议缓冲区作为一种格式没有对象图的官方支持,但protobuf-net 确实提供了这一点,并满足您的其他要求。 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; protobuf-net可以为公共和非公共领域做到这一点; 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) 这在“v2”中可用 - 再次,您可以告诉它在运行时或通过属性跳过构造函数(合同上的SkipConstructor=true

  • Must handle general object graphs, ie not only DAG but shared/bidirectional references. 必须处理一般对象图,即不仅是DAG而是共享/双向引用。

Sure; 当然; mark AsReference=true on a member 在成员上标记AsReference=true

  • Must work with framework classes (eg Serialize Dictionaries). 必须使用框架类(例如Serialize Dictionaries)。

Standard lists and dictionaries work fine; 标准列表和词典工作正常; however , I have an outstanding change request to support AsReference inside a dictionary. 但是 ,我有一个优秀的变更请求支持AsReference的字典 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 意思是, Dictionary<string, Foo> 目前不会运行Foo的图形代码,但是如果它引起你的重大痛苦,我可能会找一些时间看看这个

  • We use the [OnDeserialized/ing] attributes to provide compatibility 我们使用[OnDeserialized / ing]属性来提供兼容性

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) 命名空间等对protobuf-net一点都不感兴趣(除非你使用的是DynamicType选项)

  • it would still mean having to add parameterless constructors and protobuf annotations to all classes 它仍然意味着必须向所有类添加无参数构造函数和protobuf注释

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. 如果您可以保证不会更改字段名称,可以要求它在内部推断字段编号 - 最终在“v2”中可以在运行时指定所有内容 ,因此您通常可以编写一个运行于的小配置循环app-startup并使用反射来配置系统。 Then you do not need to change your existing code at all . 然后,你不需要改变你现有代码。

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. 试试db4o ,它不是真正的串行器,但据我所知,它可以满足您的要求(复杂类型,深度图,继承?,字典等),您不必更改对象上的任何内容,并且API非常使用方便。

It supports schema versioning/merging. 它支持模式版本控制/合并。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM