使用ProtoBuf.net的通用序列化器

本文关键字:序列化 ProtoBuf net 使用 | 更新日期: 2023-09-27 18:16:08

我正在尝试使用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<string的对象时,object>我遇到一个错误,告诉我没有为Object注册序列化器。

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

有什么建议吗?

使用ProtoBuf.net的通用序列化器

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

也就是说,DynamicType=true有一些支持,但目前还没有为您提到的字典场景启用。

然而,在大多数情况下,数据并不是真的可以是任何;更典型的情况是,预期的数据类型数量有限。当是这种情况时,可以使用稍微不同的模型(特别是非泛型基本类型,泛型子类型和一些"包括"选项)以更清晰的方式解决object问题。与大多数序列化一样,在某些情况下,可能需要有一个单独的"DTO"模型,它看起来更接近序列化输出,而不是更接近您的域模型。

最后注意:GetProperties()/Add()方法不是健壮的,因为GetProperties()不能保证成员的任何特定顺序;对于您所展示的protobuf-net,顺序很重要,因为这有助于确定要使用的密钥。即使的顺序是固定的(例如按字母顺序排序),也要注意添加成员可能是一个破坏性的更改。