3

私はCQRSとイベントソーシングを使って最初の試みに飛び込んでいます。いくつかのガイダンスが必要です。SOスタイルのレピュテーションシステムを実装したいと思います。これは、このアーキテクチャに最適のようです。

例としてSOを維持します。質問が賛成されたとすると、UpvoteCommandこれにより質問の合計スコアが増加し、が発生しますQuestionUpvotedEvent

著者のユーザーアグリゲートはQuestionUpvotedEvent、レピュテーションスコアを上げる可能性のあるサブスクライブする必要があるようです。しかし、このサブスクリプションをいつ/どのように行うかは私にはわかりませんか?Greg Youngsの例では、イベント/コマンドの処理はglobal.asaxに組み込まれていますが、これには集約IDに基づくルーティングは含まれていないようです。

QuestionUpvotedEventすべてのユーザーアグリゲートが正しくないと思われるすべてをサブスクライブするように見えます。そのようなスキームを機能させるには、イベントハンドラーは、そのユーザーが投票されたばかりの質問を所有しているかどうかを識別する動作を示す必要があります。Greg Youngは、これをイベントハンドラーコードに含めるべきではなく、単に状態の変更を伴うべきであると示唆しました。

ここで何が間違っているのですか?

どんなガイダンスでも大歓迎です。

編集

ここで話しているのは、質問とユーザーの集合体間の集合体間の通信だと思います。私が見ることができる1つの解決策は、QuestionUpvotedEventがサブスクライブされていることです。これによりReputationEventHandler、対応するユーザーARをフェッチし、このオブジェクトで対応するメソッドを呼び出すことができますYourQuestionWasUpvoted。これにより、ユーザー固有のUserQuestionUpvotedイベントが生成され、将来の再生機能が維持されます。これは正しい方向に向かっていますか?

編集2

こちらのグーグルグループに関する議論も参照してください。

4

4 に答える 4

6

私の理解では、アグリゲート自体がイベントをサブスクライブするべきではないということです。ドメインモデルはイベントのみを発生させます。イベントをサブスクライブするのは、クエリ側またはその他のインフラストラクチャコンポーネント(電子メールコンポーネントなど)です。

ドメインサービスは、複数のアグリゲートを含むユースケース/コマンドで動作するように設計されています。

この状況で私がすること:

  • VoteUpQuestionCommandが呼び出されます。
  • VoteUpQuestionCommandのハンドラーは次を呼び出します。

    IQuestionVotingService.VoteUpQuestion(Guid questionId、Guid UserId);

  • 次に、これは質問とユーザーの両方の集計に影響を与え、user.IncrementReputation(int amount)やquestion.VoteUp()などの両方で適切なメソッドを呼び出します。これにより、2つのイベントが発生します。UsersReputationIncreasedEventQuestionUpVotedEventはそれぞれ、クエリ側で処理されます。

于 2011-09-13T09:29:52.317 に答える
2

私の親指のルール:AR間通信を行う場合は、サガを使用してください。トランザクションの境界内に物事を維持し、リンクを明示的に=>処理/保守しやすくします。

于 2011-09-12T09:25:42.950 に答える
0

ユーザーアグリゲートにはQuestionAuthoredイベントが必要です...そのイベントはサブスクライブされていQuestionUpvotedEventます...同様に、QuestionDeletedEventおよび/またはサブスクライブ解除などQuestionClosedEventの適切な処理を行う必要があります。QuestionUpvotedEvent

編集-コメントによる:

質問は外部イベントソースであり、ゲートウェイを介して処理します。ゲートウェイは、リプレイを正しく処理する役割を果たします。そのため、拒否イベントなどの特別なイベントを除いて、最終結果はまったく同じになります。

于 2011-09-10T07:33:09.137 に答える
0

これは古い質問であり、回答済みとしてタグ付けされていますが、何かを追加できると思います。CQRS + ESで数か月間読んで練習し、小さなフレームワークとアプリケーションベースを作成した後、CQRSはコンポーネントの依存関係と責任を切り離そうとしていると思います。一部のリソースでは、コマンドごとに書き込みます。コマンドハンドラーで最大1つのアグリゲートを変更する必要があります(ハンドラーで複数のアグリゲートをロードできますが、変更できるのはそのうちの1つだけです)。したがって、あなたの場合、ベストプラクティスは@Tomの回答であり、sagaを使用する必要があると思います。フレームワークがsagaをサポートしていない場合(私の小さなフレームワークのように)、のようなイベントハンドラーを作成できますUpdateUserReputationByQuestionVotedEvent。その中で、ハンドラーはORORを作成UpdateUserReputation(Guid user id, int amount)UpdateUserReputation(Guid user id, Guid QuestionId, int amount)ます UpdateUserReputation(Guid user id, string description, int amount)。コマンドがハンドラーに送信された後、ハンドラーはユーザーIDによってユーザーをロードし、状態とプロパティを更新します。このタイプの処理では、より複雑なシナリオまたはワークフローを作成できます。

于 2016-10-21T08:02:06.600 に答える