2017-03-28 13 views
1

protobufでどのタイプのデ/シリアライズが実行時に分かっていないときに最良の方法はありますか?多くの不明なタイプのProtobuf

現在、私は、直列化の候補である型の型初期化子でRuntimeTypeModelを継承することを考えています。これは直列化ではうまくいくようです。しかし、別のプロセスで直列化を解除するときは、型のシリアル化に使用された同じ型のモデルを別の場所からロードする必要があります。シリアライズされたデータをディスクから再度読み込んだときに、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

ランダム思考:あなたが初期化を終了し、ディスクに焼いたシリアライザの書き込みした後、あなた.Compile(serializerName,dllPath)を使用することができます。それを参照するには、new SerializerName()を使用してインスタンスを作成し、.Serializeなどのメソッドをそこから使用してください。 dllは決して変更されません。これはまた、のメタデータを処理する必要がないことを意味します。;私たちはである可能性があります。はおそらく設定を保存する点でもっと穏やかですが、protobuf-netは現在、それをサポートするために直接何も追加していません。おそらく起動時に消費する独自の設定データを持つことが重要です。

+0

保存されたファイルごとに読み込みが必要な長時間実行されるプロセスでは、現在のAppDomainにロードされているアセンブリの数が多すぎるためにメモリリークの問題が発生する可能性があるため、 。 Model.AddとAddSubtypeの呼び出しを記録し、これらのパラメータをストリームの前に格納して、タイプをもう一度逆シリアル化する必要があるときにAPI呼び出しを再生すると思います。 –

関連する問題