2012-04-28 15 views
1

DrawingBrushを含むBL構造をシリアル化する必要があります。次のように私はそれを書き換えました:protobuf-netの問題でWPF DrawingBrushをシリアライズ

[ProtoContract] 
public class BaseProtoBuf : INotifyPropertyChanged, IFormattable 
{ 
    [ProtoMember(1)] 
    public string ID { get; set; } 
    // Bunch of properties of .net primitive types 
    // .. 
    private DrawingBrush _geometry; 
    [ProtoMember(9)] 
    [Browsable(false)] 
    public DrawingBrush Geometry 
    { 
      get { return _geometry; } 
      set 
      { 
       _geometry = value; 
       ScaleDrawing(); 
      } 
    } 
} 
[ProtoContract] 
[ProtoInclude(1, typeof(string))] 
// All other includes 
[ProtoInclude(9, typeof(DrawingBrush)] 
public class DerivedProtoBuf : BaseProtoBuf, ICloneable 
{   
    // Some additional properties of primitive types, annotated starting with ProtoMember 10 and so on 
} 

私は次のコードを実行していシリアライズするには:

const string fileName = "Protobuf.bin"; 
using (var file = File.Create(fileName)) 
{ 
    file.Position = 0; 
    var testBase = new BaseProtoBuf 
            { 
             Height = 100, 
             Width = 100, 
             Name = "Test 1", 
             OffsetX = 200, 
             OffsetY = 200, 
             Geometry = sourceList[0].Geometry // some not-null DrawingBrush 
            }; 
    Serializer.Serialize(file, testBase); 
    file.Position = 0; 
    var restored = Serializer.Deserialize<BaseProtoBuf>>(file); 
} 
} 

を私は、派生クラスのオブジェクトをシリアル化する必要がありますが、基本シリアル化中に、私は「いいえ、適切なデフォルトをを取得していませんDrawingBrushエンコーディングが見つかりました "。 DrawingBrushはオブジェクトによってはnullになる可能性がありますが、テストではそうではありません。適切にシリアル化するための回避策1)非ヌルのBaseオブジェクトDrawingBrush 2)nullのDrawingBrushを持つ派生オブジェクト?前もって感謝します。

答えて

3

正しいRuntimeTypeModel構成実行時にフレームワークのための所望の値から:迅速な答えを

RuntimeTypeModel.Default.Add(typeof(Brush), false) 
       .AddSubType(300, typeof(SolidColorBrush)); 
RuntimeTypeModel.Default.Add(typeof(SolidColorBrush), false) 
       .Add("Color"); 
RuntimeTypeModel.Default.Add(typeof(Color), false) 
       .Add("A", "R", "G", "B"); // needed for proper color serialization 
RuntimeTypeModel.Default.Add(typeof(SolidColorBrush), false) 
     .Add("Color"); 
RuntimeTypeModel.Default.Add(typeof(DrawingBrush), false) 
     .Add("Stretch", "Drawing"); 
RuntimeTypeModel.Default.Add(typeof(Drawing), false) 
     .AddSubType(100, typeof(DrawingGroup)) 
     .AddSubType(200, typeof(GeometryDrawing)); 
RuntimeTypeModel.Default.Add(typeof(DrawingGroup), false) 
     .Add("Children"); 
RuntimeTypeModel.Default.Add(typeof(Pen), false) 
     .Add("Brush", "Thickness", "LineJoin"); 
RuntimeTypeModel.Default.Add(typeof(GeometryDrawing), false) 
     .Add("Brush", "Geometry", "Pen"); 
+0

Eeshのように見える....「楽しい」; Pはうまくいっていた。マイナーフィードバック。 "varint"エンコーディングの仕組みのために、サブタイプ(300/200/100)のタグ番号を小さくすると、数バイトを節約できます。しかし、何も顎を落とすことはありません。 –

2

契約が定義されていないため、DrawingBrushは直ちにSerializableではありません。ここではさまざまなオプション:タイプはかなり単純であれば、あなたは「サロゲート」を使用して、いくつかのケースでは

  • を必要に応じてプロパティ/サブタイプなどに追加して、RuntimeTypeModelを経由して、実行時に契約を

    • 設定できますオンザフライDTOとして動作するために使用される双方向変換演算子を持つタイプの方がいいかもしれません。また、代理はRuntimeTypeModelで指定できます。 「サロゲート」は既存のモデルを使用しますが、必要に応じてDTOタイプを交換します。そうでない場合は、モデル内のフレームワーク固有の型を避け、必要な情報だけを使用してDTO型を使用してください。その構造簡単なWPFブラシのシリアル化のための
  • +0

    おかげで、私はので、オプション#1を選択する必要があると思います(実際には、それらを構築するために得られるのは、文字列の束を持つ外部ソースからの明白なXMLであるため、管理オブジェクトを作成して文字列に戻すことはオプションではありません)後で荷を積む。複雑なフレームワークのデータ型の契約構成の例を指摘できますか? – Jaded

    +0

    私は全体のリポジトリをチェックアウトしてシリアライザに少し掘り下げましたが、IProtoSerializerは内部的なので、ライブラリの外で実装するつもりはないと思います。また、基になる型のRuntimeTypeModelの手動作成も試しましたが、コンパイル - BuildAllSerializersのエラー:MetaTypeオブジェクトにヌルのシリアライザがあり、*シリアライザがSystem.Windows.Media.DrawingBrush *エラーとして定義されていません。 – Jaded

    +0

    @ Jaded RuntimeTypeModel.Default.Add(typeof(DrawingBrush)、false).Add( "x"、 "y"、 "z");たとえば、はるかに微妙な設定が可能です。 –