序列化/反序列化协议缓冲区

时间:2016-12-30 17:49:46

标签: c# serialization mapping protocol-buffers

我目前正在使用Protocol Buffers(版本3 C#)。 我正在向不同的服务发送消息。 并且目前正试图将存储在某些消息中的一些数据保存到数据库中(实际上可以是任何类型)。

问题是 byte [] 被创建为类型 ByteString List< T> 创建为 RepeatedField< T> 。 现在我遇到的问题是我没有成功地100%成功地序列化或反序列化它们。

基本类型就像魅力一样,但协议缓冲区自己的类型可能是一个挑战。

我尝试了 AutoMapper 并创建了使ByteString可以序列化/反序列化的映射但是RepeatedField很难,因为它只是readonly并且有一个私有的setter而且在构造函数中是不可设置的。

我无法让AutoMapper正确映射到它,如果在此过程中遇到更多麻烦并且想知道是否有更简单的方法在数据库中保存消息,我不会感到惊讶吗?

我已经阅读了旧版本的protobuf(如果我没有记错的话)那里有所谓的构建器,你可以访问每个消息的属性,这些属性是可变的,并且可以使序列化/反序列化更容易。或者是否有更明显的方式来访问数据并将其存储在我没有看到的数据库中?

我理解消息不可变的原因,但实际上没有直接的方法将包含数据保存到数据库中吗? 感觉像一个重要的特征。

PS:我知道有一个protobuf-net解决方案可以处理序列化/反序列化,但它只支持protobuf v.2,而且我很依赖于v.3特性,例如 Any

2 个答案:

答案 0 :(得分:2)

我已将AutoMapper 6.1.1映射到protobufs 3 RepeatedField<&gt ;.我确信可以改进反射,但AutoMapper配置是:

void Configure(IMapperConfigurationExpression cfg)
{
    cfg.CreateMap<ProtoThings, HasListOfThings>().ReverseMap();

    bool IsToRepeatedField(PropertyMap pm)
    {
        if (pm.DestinationPropertyType.IsConstructedGenericType)
        {
            var destGenericBase = pm.DestinationPropertyType.GetGenericTypeDefinition();
            return destGenericBase == typeof(RepeatedField<>);
        }
        return false;
    }
    cfg.ForAllPropertyMaps(IsToRepeatedField, (propertyMap, opts) => opts.UseDestinationValue());
}

答案 1 :(得分:0)

如果您知道模型中的哪个成员是protobuf重复字段,则可以指定映射目标值,而不是重复字段本身。这避免了原虫重复字段没有为其定义公共“集合”的麻烦。

CreateMap<Model, ProtoModel>().ForMember(dest => dest.MyRepeatedCollection, opt => opt.UseDestinationValue());