具有许多未知类型的Protobuf

时间:2017-03-28 21:29:39

标签: c# protobuf-net

当我在运行时不知道使用protobuf对哪些类型进行de / serial化时,最好的方法是什么?

目前我正在尝试将类型初始值设定项中的RuntimeTypeMode扩展为序列化的候选类型,这对于序列化似乎非常有效。但是当在不同的进程中反序列化时,我需要从用于序列化类型的某个地方加载相同类型的模型。是否可以将RuntimeTypeModel序列化为磁盘,以便稍后在从磁盘读取序列化数据时重用它?理想情况下,我会将模型放入序列化流中,以获得完整的自描述对象模型。或者我是否需要记录步骤并将此数据放在序列化流中?

可以创建一个标题,其中包含实际数据的偏移量和运行时类型模型以及非常好的长度。或者是否有更好的方法来处理插件架构,在序列化时我已经注册了所有类型但在解除序列化时我可能需要从各自的程序集中加载某些类型,因为代码还没有被触及?

using ProtoBuf;
using ProtoBuf.Meta;
using System.Collections.Generic;
using System.IO;

namespace protobuf
{
    [ProtoContract]
    public interface IAbstraction
    {
        [ProtoMember(1)]
        string Name { get; set; }
    }

    [ProtoContract]
    public class Base : IAbstraction
    {
        static Base()
        {
            ProtobufTypeModels.MainModel.Add(typeof(IAbstraction), true).AddSubType(101, typeof(Base));
        }

        [ProtoMember(1)]
        public string Name { get; set; }

        [ProtoMember(2, AsReference =true)]
        public List<IAbstraction> Instances = new List<IAbstraction>();
    }

    [ProtoContract]
    public class Next : Base
    {
        static Next()
        {
            ProtobufTypeModels.MainModel.Add(typeof(IAbstraction), true).AddSubType(100, typeof(Next));
        }

        [ProtoMember(1)]
        public string NextName { get; set; }
    }

    public static class ProtobufTypeModels
    {
        public static readonly RuntimeTypeModel MainModel = TypeModel.Create();
    }


    class Program
    {
        static void Main(string[] args)
        {
            Base b = new Base { Name = "Alois" };
            b.Instances.Add(new Next { Name = "Base", NextName = "Christian" });
            b.Instances.Add(new Base { Name = "SecondBase", Instances = b.Instances });
            var mem = new MemoryStream();
            ProtobufTypeModels.MainModel.Serialize(mem, b);
            mem.Position = 0;
            var deser = (Base) ProtobufTypeModels.MainModel.Deserialize(mem, null, typeof(Base));
        }
    }
}

1 个答案:

答案 0 :(得分:1)

随机思考:在完成初始化并将烘焙的序列化程序写入磁盘后,可以使用.Compile(serializerName,dllPath);然后你可以引用它,使用new SerializerName()创建实例,并使用{/ 1}}等方法从那里。 dll永远不会改变。这也意味着它永远不必再次处理任何元数据;没有反射,没有IL发射等等。

除此之外:我们可能可能在存储配置方面做一些更温和的事情,但是:protobuf-net目前没有直接添加任何内容来支持它,它可能会更多与您相关的是您自己定制的配置数据,您只需在启动时使用。