ASP.NET MVC3 / NHibernate アプリケーションには、ドメイン オブジェクトに関連するさまざまなイベントを起動して処理する必要があります。たとえば、Order
オブジェクトにはOrderStatusChanged
やなどのイベントが含まれる場合がありますNoteCreatedForOrder
。ほとんどの場合、これらのイベントによってメールが送信されるため、MVC アプリにそのままにしておくことはできません。
私は、Udi Dahan のDomain Eventsや、この種のことを行う方法についての他の多くの考えを読み、イベント メッセージを処理する NServiceBus ベースのホストを使用することにしました。私はいくつかの概念実証テストを行いましたが、これはうまくいくようです。
私の質問は、どのアプリケーション層が実際にイベントを発生させるべきかということです。問題のオブジェクトが正常に永続化されるまでイベントを発生させたくありません (永続化が失敗した場合、メモが作成されたという電子メールを送信できません)。
もう 1 つの懸念事項は、場合によっては、イベントが集約ルートの下にあるオブジェクトに関連付けられることです。上記の例では、コレクションにNote
追加して順序を保存することで a が保存されます。これは、が保存されOrder.Notes
たときにどのイベントを起動する必要があるかを評価するのが難しくなるという問題を引き起こします。Order
更新されたコピーを保存する前に、オブジェクトの現在のコピーを取得して違いを探す必要はありません。
UI がこれらのイベントを発生させるのは適切ですか? どのイベントが発生したかを認識し、サービス層がオブジェクトを正常に保存した後でのみ、イベントを起動できます。コントローラがドメイン イベントを発生させると、何かがおかしいように見えます。
正常に永続化された後、リポジトリはイベントを発生させる必要がありますか?
イベントを完全に分離し、リポジトリにオブジェクトを格納し、それ
Event
をポーラー サービスによって取得して、NServiceBus のイベントに変換する (またはポーラー サービスから直接処理する) 必要がありますか?これを行うより良い方法はありますか?オブジェクトが永続化された後にのみ、サービス層によって起動されるイベントをドメイン オブジェクトでキューに登録することはできますか?
更新:私はサービス層を持っていますが、特定の集約ルートが保存されたときにどのイベントを起動する必要があるかを決定するために、比較プロセスを実行するのは面倒で過剰に思えます。これらのイベントの一部は詳細 (「注文ステータスが変更されました」など) であるため、オブジェクトの DB コピーを取得し、プロパティを比較してイベントを作成し、新しいオブジェクトを保存してから、イベントが発生したときに NServiceBus に送信する必要があると思います。保存操作が正常に完了しました。
アップデート
以下に投稿した回答(以下の方法)に続いて、私が最終的に行ったことは、ドメインエンティティEventQueue
にList<IDomainEvent>
. 次に、ドメインへの変更に値するイベントを追加しました。これにより、ロジックをドメイン内に保持することができました。これは、エンティティ内で何が起こっているかに基づいてイベントを発生させるため、適切であると考えています。
次に、サービス レイヤーでオブジェクトを永続化するときに、そのキューを処理し、実際にイベントをサービス バスに送信します。最初は、ID PK を使用するレガシー データベースを使用することを計画していたので、これらのイベントを後処理してエンティティの ID を入力する必要がありましたが、最終的には、Guid.Comb
その手順をスキップできる PK に切り替えることにしました。