2017-02-08 5 views
2

私は別のCQRS samplesを見てきましたが、そのほとんどはUnitOfWork(つまり、の場合はDataContext)を保存しないコマンドハンドラを使用しています。このようなもの:CQRSコマンドハンドラでUnitOfWorkを保存しないのはなぜですか?

public void Handle(Command message) 
    { 
     var course = Mapper.Map<Command, Course>(message); 

     _db.Courses.Add(course); 
    } 

通常、要求が処理されると、保存(トランザクションコミット)はバックグラウンドで行われます。

私はこのアプローチを多くの主要なCQRSの人たちから見てきましたが、私はその考えを聞いたことがありません。

このアプローチの最大の問題は、ハンドラ呼び出しが返された直後にエンティティIDを取得する必要がある場合です(かなり発生します)。それを回避する方法は明らかです(つまり、Guidを使い、データベースから一意のIDを事前に要求するなど)が、不器用に見えます。

しかし、このアプローチの利点は何ですか?理論的には、リクエストごとに複数のハンドラがある場合に、複数のデータベースラウンドトリップを行わないようにすることができます。しかし、それはあまり起こりません。私の頭に浮かぶもう1つの利点は、そのルーチンにSaveルーチンを入力する必要がなく、自動的に実行されるということです。それはちょっといいですが、それはId生成の問題を過大評価していますか?

答えて

1

なぜCQRSコマンドハンドラはUnitOfWorkの保存を除外しますか?

私は、ドメインオブジェクトのライフサイクル第6章、それはエヴァンス、Domain Driven Designから始まると思います。データベース・アクセスの技術的課題に対処するための技術のいかだがあり

....

しかし、そうであっても、失われたものをメモを取ります。私たちはもはや私たちのドメインモデルの概念を考えていません。私たちのコードはビジネスについての情報を伝えることはなく、データ検索の技術を操作することになります。

コードのこの時点で、我々はドメインモデルで作業をしているのではなくデータモデルを見ているということでアイデア。

リポジトリが非常に強調され、今、単純な、意図-暴露のインタフェースに話し、それがモデル

エヴァンスの面で必要なものを求めることができ、クライアントからの莫大な負担を持ち上げますこれについて、トランザクションのコンテキストで

クライアントにトランザクション制御を残す。 REPOSITORYはデータベースに挿入され、データベースから削除されますが、通常は何もコミットしません。たとえば、保存後にコミットすることが魅力的ですが、クライアントはおそらく、作業単位を正しく開始およびコミットするためのコンテキストを持っています。 REPOSITORYが手を離しておくと、トランザクション管理が簡単になります。

いくつかの追加の注意事項:あなたは、ハンドラの呼び出しが返された後に(かなり多くをたまたま)エンティティID権を取得する必要があるときに、このアプローチの

最大の問題は、例です。

これは通常、間違った問題と戦っていることを示しています。 Marc de Graauw、Nobody Needs Reliable Messagingを参照してください。

+0

私はすべてがリポジトリで少し意味をなさないように感じます。私たちがDataContextを使って直接作業しているとき、私たちはドメインで作業していないので、データストアを変更します。そして、私たちは最後のステップ(私たちが修正したものを保存する)をしないで、ドメインオブジェクトの操作を分離してデータストアで作業するふりをします。 – SiberianGuy

1

コマンドハンドラの重要な機能は、例外(例外を除く)が返されないことです。微妙な点ですが、すべてのコマンドハンドラが何も返さないことを知っていれば、膨大な量のコードを節約し、より堅牢なコードベースを単純化したり、作ることができます。

しかし、何も返さない場合は、プロセスの開始時にIDが必要な場合があります。私はGUIDを使用することはこれに優雅な解決策だと思います。

データベースからユニークなIDをプリフェッチするのは問題があり、可能ならばその方法を避けたいと思います。ここで

は、いくつかの利点があります:

  1. すべてのコマンドハンドラは、したがって、すべてのコマンドハンドラをサポートしているヘルパーのコードを書くことができ、共通のインタフェース
  2. を持つことになります。例えばコマンドルーター、セキュリティとアクセス許可のチェック、ロギング、パフォーマンスモニタリング、メッセージキューイング...
  3. 書く必要があるコードの量を大幅に減らすことができます。
  4. 書く必要があるコードの複雑さを大幅に軽減できます
  5. テストは、これらが私の頭の上からほんの一部です

はるかに簡単に、より堅牢です。

なぜ作業ユニットは含まれていませんか?

あなたは簡単な答えです。しかし、私はハンドラから永続性の責任を取り除くのが好きです。ハンドラはそれを呼び出すことができますが、実際の永続性は他の場所で行われます(ほとんどの場合、私の好みはイベントストアにあります)。

+0

答えてくれてありがとうございましたが、私はGuidsをエレガントなものと呼ぶ限りは行っていません:) – SiberianGuy

+0

どうしてですか?データベースに依存しないグローバルに一意のIDを作成する。私はそれがかなりクールだと思います。 – Codescribler

+0

まあ...彼らは醜いです:)そして、あなたはURLにGuidベースのIDを表示する必要がある場合、それは右に感じることはありません – SiberianGuy

関連する問題