带有 ProtoBuf.net 的通用序列化器

Posted

技术标签:

【中文标题】带有 ProtoBuf.net 的通用序列化器【英文标题】:Generic serializer with ProtoBuf.net 【发布时间】:2011-11-28 03:56:20 【问题描述】:

我正在尝试使用 protobuf.net v2 编写通用序列化程序。但是,我遇到了一些问题,这让我想知道我正在做的事情是否是不可能的。要序列化的对象属于我无法访问的不确定类型,因此我尝试遍历该对象并将其属性添加到类型模型中。

        var model = TypeModel.Create();
        List<string> propertiesToSerialize = new List<string>();
        foreach (var property in typeToSerialize.GetProperties())
        
            propertiesToSerialize.Add(property.Name);
        
        model.AutoAddMissingTypes = true;
        model.Add(typeToSerialize, true).Add(propertiesToSerialize.ToArray());

对于只包含原语的简单对象,这似乎工作得很好。但是,当使用包含 Dictionary 的对象时,我遇到一个错误,告诉我没有为 Object 注册序列化程序。

我确实看过serializing a Dictionary<string,object> in ProtoBuf-net fails,但似乎建议的解决方案需要一些知识和对被序列化对象的访问权限。

对我如何进行有什么建议吗?

【问题讨论】:

【参考方案1】:

protobuf-net 并未设定能够序列化每个场景(尤其是那些由 object 主导的场景),就像 XmlSerializerDataContractSerializer 的场景一样他们不能建模。特别是,protobuf 格式的元数据完全缺乏(它非常高效的部分原因)意味着它只打算被预先知道数据结构的代码使用 - 这如果太多是不可能的object

也就是说,通过DynamicType=true 提供一些支持,但目前不会为您提到的字典场景启用。

不过,在大多数情况下,数据实际上并不是任何东西;更典型的是,预期数据类型的数量是有限的。当 是这种情况时,object 问题可以使用稍微不同的模型(特别是非泛型基类型、泛型子类型和一些“包括”选项)。与大多数序列化一样,在某些情况下可能需要一个单独的“DTO”模型,它看起来更接近序列化输出而不是域模型。

最后一点:GetProperties()/Add() 方法并不可靠,因为 GetProperties() 不保证成员的任何特定顺序;以您展示的方式使用 protobuf-net,顺序很重要,因为这有助于确定要使用的密钥。即使顺序固定(例如按字母顺序排序),请注意添加成员可能是一项重大更改。

【讨论】:

是的,这就是我的印象。我希望在不对 protobuf-net 或 eventstore 进行任何更改的情况下将协议缓冲区用于@Jonathan Oliver 的事件存储库,但我将不得不修改事件存储库。感谢您的深入回答,尤其是最后的说明,我没想到。

以上是关于带有 ProtoBuf.net 的通用序列化器的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 带有 Dart 的通用 json 序列化器

protobuf.net 和条件序列化

Protobuf-net - 啥被序列化了?

Protobuf .NET 后反序列化处理程序

使用 DataContract 属性时 ProtoBuf.NET 未序列化

列表的 Protobuf.net 对象图序列化