ドメインイベントハンドラーはいつ登場しますか?
-
28-10-2019 - |
質問
2つの総根と1つの通常のエンティティの単純な試験ドメインがあります。Tenant
, UserGroup
と User
この特定のサンプルでは Tenant
と User
2つを補います 集計.
UI/サービスレイヤーからコマンドが受信されると、書き込みのみドメインを操作するコマンドハンドラーに到達します。
あなたはそれを言うことができます User
であるはずではありません 集計 他の人から参照されるので、まったく通常のエンティティになることはできません。 (はい?)
これらの2つのregregaterootsは通信する必要があります。 a User
aに属さずに作成することはできません UserGroup
, 、これはの境界のあるコンテキストのエンティティです Tenant
. 。おそらく、それは単純な制約であるため、コンストラクターを介してユーザーを作成することができます。 User.Create(TenantId, UserGroupId)
それはaを生成します DomainEvent
日付、集約バージョン、および集計(ユーザーの)。今、私たちはぼやけた部分に到達します。
このイベントを店にコミットすることを開いて、このイベントはバスに放送されます(記憶、何でも)。これは、コマンドハンドラーと同様に、ドメインのイベントハンドラーが作成されたユーザーをキャッチし、通知/操作するポイントです。 Tenant
's UserGroup
追加するには UserId
?
これを解決することについての私の考えは、完全に間違った方向に進むのですか?
解決
a Saga
あなたが探しているものかもしれません。
簡単に言えば、SAGAは、特定のイベントや問題のコマンドをさまざまな集計のルーツ、あるいはコンテキストの境界を越えて聴くイベントハンドラーとして実装できます。
あなたの場合、それは次のようになるかもしれません:
public class RegisterUserSaga : Handles<UserCreated>
{
public void Handle<UserCreated>(UserCreated evnt) {
var tenantId = // you probably know how to find this
var groupId = // same here
var command = new RegisterUserForTenant(evnt.UserId, tenantId, groupId);
Bus.Send(command);
}
}
サガスの詳細を読んでください この記事 リナト・アブドリンまたはウォッチ 「CQR、人種条件、サガ - ああ!」 ウディ・ダハンによって
アップデート:
コメントで拡張された議論の後、これが異なる角度からどのように機能するかを示しようとします(先の擬似コード)。これは、可能な解決策にさらに光を当てることを願っています。
// Aggregates:
Tenant
Guid TenantId
List<Guid> UserGroups
UserGroup
Guid UserGroupId
List<Guid> Users
User
Guid UserId
Some more details
// Commands:
RequestRegistration(userId, userGroupId, user details)
CreateUser(userId, user details)
AddUserToGroup(userId, userGroupId)
// The initial command would be:
RequestRegistration (leading to a RegistrationRequested event)
// The Saga handles the RegistrationRequested and all subsequent events
UserRegistrationSaga
Handle(RegistrationRequested)
-> send CreateUser command (which eventually leads to a UserCreated event)
Handle(UserCreated)
-> send AddUserToGroup command (-> UserAddedToGroup event)
Handle(UserAddedToGroup)
-> Done