2011-01-14 9 views
18

私たちのアプリケーションでは、ドメインモデルで何か変わったときにドメインイベントを発生させます。イベントハンドラによって実行されるタスクの一部は、イベント発生時に使用された同じトランザクション内で実行されなければならず、他のタスクはこのトランザクション外で実行されなければなりません。次に、例えばトランザクションの内部または外部でドメインイベントを発生させる必要がありますか?

、注文ラインをOrderエンティティに追加されると、OrderLineAddedドメインイベントが発生した

、一つのドメインイベントはドメインモデルの状態を変化させる(したがって、同じトランザクションで実行されなければなりません)、トランザクションが完了したら、UIを更新する必要があります。

どのようにこの問題にアプローチしますか?

  1. トランザクション内に1つ、トランザクション外に2つのイベントを発生させます。
  2. トランザクションの内部でイベントを発生させますが、イベントハンドラを使用してAsyncリクエストを送信してUIを更新しますか?

オプション1は、イベント名が何らかの形でトランザクション内外に伝達されなければならないので混乱しますが、オプション2のドメインイベントハンドラではトランザクション内から同期的に呼び出されると仮定する必要があります。

おそらくもっと良いアプローチがありますか?

答えて

16

私も同様の問題がありました。ドメインモデルはイベントを公開していました(Udi Dahanの技術ではhereと記載されています)。次に、何かがうまくいかず、後でトランザクションがロールバックされても、UI関連のハンドラが呼び出されることに気付きました。

これを修正するために、別の種類のイベントハンドラをシステムに導入しました。私はITransactionalEventHadnelerINonTransactionalEventHandlerです。前者はすぐにDomainEvents.Publish()メソッドで同期的に呼び出されました。後者は、トランザクションがコミットされるとすぐに(System.Transactionsフックを使用して)呼び出されるようにキューに入れられました。このソリューションはうまく機能し、読みやすく保守性がありました。

+0

これは素晴らしいソリューションのようですが、トランザクションイベントを非トランザクションイベントと区別するためにイベントの名前をどのように指定しますか? – Andronicus

+0

私は実装されたインターフェースだけに頼っていました。命名規則はありませんでした。 –

+1

@Szymon:それはしばらくしていますが、 "フック"とは[TransactionCompleted](http:// msdn。microsoft.com/en-us/library/system.transactions.transaction.transactioncompleted.aspx)イベントは、.NETの 'Transaction'クラスにありますか?例がありますか? – dstj

1

私は両方のアプローチは、良いことだけであなたのコードのすべての部分で同じアプローチに固執すると思う:

  1. あなたが2つ(またはそれ以上)のイベントハンドラ、ドメインのコンテキストに1つずつ必要になりますモデルは、トランザクションスコープ内にあり、UIのような補助的なコンテキストのための他のものです。あなたのドメインコードは、コードの他の部分が何をしているのか気にしてはいけません。ドメインデータの変更について通知するだけです。
  2. ドメインコードイベントハンドラメソッドは、非同期イベントをUIまたは他のモジュールに送信することがあります。ドメインイベントは同期している必要があります。そうしないと、トランザクション性を維持するために2フェーズコミットが必要になります。

私は個人的にはドメインコードをより清潔に保ち、非同期通信を使用することでコアと他のモジュールが分離されるため、外部モジュールの問題はコアの動作を妨げません。一方、オプション1がより有利である状況が存在する可能性がある。

関連する問題