2

しばらくの間、CQRS/DDD の原則とパターンを調査しており、ストレージ モデルを WriteModel と ReadModel に分割したサンプル プロジェクトの実装を開始しました。WriteModel は単純な NoSQL に似たデータベースを使用します。このデータベースでは、集計がキーと値のスタイルで格納され、値は集計の単なるシリアル化されたバージョンです。

現在、ドメイン モデルの集約をストレージ内外でシリアライズおよびデシリアライズするために ProtoBuf-Net を検討しています。この投稿以外に、この分野で ProtoBuf-Net を使用するためのガイダンスやヒントは見つかりませんでした。要点は、集約のシリアライゼーションとデシリアライゼーションの (理想的な) 要件は、ドメイン モデルがこのインフラストラクチャの問題について可能な限り知識を持たないようにすることです。これは、次のことを意味します。

  1. クラスに属性はありません
  2. シリアル化のためだけに、コンストラクター、ゲッター、セッター、またはその他のコードはありません。
  3. 可能な任意の (カスタム) タイプを使用し、シリアル化/逆シリアル化する機能。

これまでのところ、完全に正常に機能する集計の最初のバージョンのシリアル化のみを実装しました。-instance を使用してRuntimeTypeModel.Default、実行時に MetaModel を構成し、UseConstructor = falseどこでも使用できるようにします。これにより、シリアライゼーションの仕組みをドメイン アセンブリから完全に分離できます。ProtoBuf-Net がフィールドを有効なインスタンスに逆シリアル化した後、ジャストインタイムでフィールドを初期化できるようにする、カスタムの逆シリアル化後のメカニズムも実装しました。したがって、次のようなクラス AggregateA があるとします。

[Version(1)]
public sealed class AggregateA
{
    private readonly int _x;
    private readonly string _y;

    ...
}

次に、シリアライゼーション ライブラリで、次の行に沿って何かをコード化します。

var metaType = RuntimeTypeModel.Default.Add(typeof(AggregateA), false);
metaType.UseConstructor = false;
metaType.AddField(1, "_x");
metaType.AddField(2, "_y");
...

ただし、ここまでは基本的なシナリオしか実装していないことに気付きました。現在、モデルのバージョン管理にどのようにアプローチするかを考え始めています。タイプ A がタイプ A1 と A2 に分割された、より大きなリファクタリング シナリオに特に興味があります。次に例を示します。

[Version(2)]
public sealed class AggregateA1
{
    private readonly int _x;

    ...
}

[Version(2)]
public sealed class AggregateA2
{
    private readonly string _y;

    ...
}

シリアル化された AggregateA のインスタンスの束があり、ドメイン モデルが AggregateA1 と AggregateA2 しか認識していないとします。このシナリオを ProtoBuf-Net でどのように処理しますか?

2 番目の質問は、ポイント 3 に関するものです。追加の構成作業を行う場合、ProtoBuf-Net は任意の型を処理できますか? -typeを使用するときに発生する例外について読んだことがありますDateTimeOffset。これにより、すべての型をすぐに使用できるフレームワークでシリアル化できるわけではないと思いますが、これらの型を RuntimeTypeModel に登録することでシリアル化できますか? 私もそこに行きたいですか?それとも、単純なもの以外の一般的な .NET 型をシリアル化することを忘れた方がよいでしょうか?

4

1 に答える 1

1

protobuf-net は、予測可能な既知のモデルで動作することを目的としています。実行時にすべてを構成できることは事実ですが、A1/A2シナリオをどのように処理するかについては考えていません。これは、サポートされているシナリオではないためです(私の弁護では、ほとんどのシナリオでうまく機能しているとは思えません)。シリアライザー)。私の頭の上で考えてみると、構成/マッピングデータがどこかにある場合、単純に2回逆シリアル化できます。AggregateA1._xつまり、 にマップし1、 にAggregateA2._yマップすることを伝えている限り2、次のことができます。

object a1 = model.Deserialize(source, null, typeof(AggregateA1));
source.Position = 0; // rewind
object a2 = model.Deserialize(source, null, typeof(AggregateA2));

ただし、より複雑な調整を行うには、追加の検討が必要になります。

Re "arbitrary types"... define "arbitrary" ;p 特に、一部の変換に役立つ「代理」型がサポートされていますが、非常に具体的な「問題ステートメント」がなければ、完全に回答することは困難です。

概要:

protobuf-net には、シリアライゼーションを意識したシナリオ (属性など) と非意識のシナリオ (ランタイム構成など) の両方を含む意図された使用法がありますが、よりオーダーメイドのさまざまなシナリオ (生のリーダーにドロップできるようにする) でも機能します。必要に応じて /writer API)。考えられるすべてのシリアライゼーション シナリオに直接適合することを保証するものではありません。

于 2013-05-22T13:45:38.117 に答える