1

ここで、protobuf-net は SAX パーサーのように使用できると述べましたが、解析するオブジェクトの多かれ少なかれ完全な記述を必要としない例を見つけることができませんでした。

(ポイント2にスキップ)質問については、1)コンテキストを提供するだけです)

1) おそらく、最初にいくつかのコンテキストを提供する必要があります。

私は現在、プロジェクトで JSON.Net を使用しており、さまざまな型のシリアル化方法をカスタマイズするためにいくつかの JSONConverters を作成しました。基本的に、すべての主要な型には手書きのシリアル化命令 (ReadProperty、ReadValue など) があります。

私がこれを行った理由と場所の例:

  • 特定のオブジェクトが実行時にMetaTypeどのように動作するかを記述するクラスがあります。ValueこれらのValueオブジェクトには、Typeシリアル化されるプロパティがあります。MetaTypeConverter は、このプロパティをシリアル化するときに の名前のみを返し、MetaType逆シリアル化するときにその名前を使用して対応する inf を取得します。その理由は、型の名前で十分であり、MetaTypeクラスをシリアライズするには面倒すぎて、結果の JSON がよりコンパクトになるためです。
  • いくつかのオブジェクトには、シリアル化する必要のない値を含むコレクションがあります。これは、オブジェクトが存在しない場合に基づいてそれらを再作成できるためMetaTypeです。コンバーターはこれらのコレクションをフィルタリングし、デフォルト値ではない値のみを格納します。JSON.Net には、プロパティがデフォルト値に設定されたときにシリアル化されないようにする属性がありますが、デフォルト値をフィルタリングする組み込みの方法は知りません。コレクションから。

私の目標は何ですか:

私はすでに大量の手書きのシリアル化コードを持っているので、OR-Mapper を取り除きたいと思っています。その理由は、古い JSON 形式を読み取り、必要な移行手順 (データの追加、不要になったデータの無視など) を実行できるマイグレーターをより簡単に作成できるためです。OR-Mapper を使用すると、古い形式を解析して古い型を新しい型に変換するために古い型が必要になります。これは有効な戦略ですが、手書きのコードがあるため、非常に細かい移行手順を実行して対応することができます。ほとんどすべての変更。基本的にはより強力で、古いオブジェクト モデルは必要ありません。

2) では、実際の質問は何ですか?

protobuf-net を使用して、ストリームとの間で多かれ少なかれ手動でデータの読み取り/書き込みを行うことはできますか、または 他の方法 (たとえば、RuntimeTypeModel?) で (非) シリアル化に対して同様の力を発揮できますか?

上記の例を使用するには:

  • type のプロパティを持つオブジェクトがありますがMetaType、全体をシリアル化する代わりにMetaType、文字列または ID のみを保存したいと考えています。逆シリアル化するとき、文字列または ID を使用して正しい値を取得しますMetaType(<= パーサーは ID を保存/読み取るだけで済みます。ルックアップを行います)
  • シリアライゼーションでコレクションをフィルタリングし、特定の基準を満たすオブジェクトのみを保存できるようにしたいと考えています。
  • 古いフォーマットを読み込んで、必要に応じてデータを移行できるようにすることで、古いフォーマットをサポートできるようにしたいと考えています。デシリアライゼーションを分岐するか、さまざまなタイプのオブジェクト (v1、v2) を作成するために使用できるバージョン番号を既に保存しています。パーサー レベル (オブジェクトが作成される前) で素晴らしいでしょう。

疑似コードの例 (上記が意味をなさない場合):

int version = Reader.ReadInt()
// [...] decide how to proceed based on version
var typeName = Reader.ReadString()
var type = MetaType.For(typeName)
// [...] read some more properties
return new ValueObject(type, property1, property2)

protobuf-netで同様のことが可能/推奨されていますか? (例/ドキュメントまたはチュートリアルへのリンクは素晴らしいでしょう – ProtoReader クラスがあることは知っていますが、それを使用することになっているかどうかはわかりません/ドキュメントなしで作業するのに十分賢いかどうかはわかりません)

編集:
可視性を高めるために、ここにマークのコメントを追加します。

ProtoReader/の生の使用例は、ここProtoWriterにあります(コードへの直接リンク)。

4

1 に答える 1

1

そのほとんどは可能です。最も生のレベルでは、ProtoReader は基礎となるストリームを読み取るための完全な API を備えています。「意図したとおりにフィールド1」(バージョンなど)を読みたいだけであることがわかっている場合は、それだけでモデルをセットアップし、ライブラリに面倒な作業をさせることができます:

[ProtoContract] class VersionStub {
    [ProtoMember(1)] public int Version {get;set;}
}

同じモデルの互換性のないバージョンが複数ある場合は、異なる RuntimeTypeModel インスタンスを作成して個別に使用できます (パフォーマンスのために、可能であればモデルをキャッシュして再利用する必要があります)。

ただし、API は既存の具象型に基づいています。実行時にマップを構成できますが、現在、DTO 型をその場で作成することはできません。出来た。とはいえ、すでに十分な量のメタプログラミングが組み込まれています...

私は質問に答えましたか?それとも違う?

于 2013-02-26T18:33:32.547 に答える