DDD中两个有界上下文之间的通信

won*_*rld 26 domain-driven-design cqrs domain-events bounded-contexts

我在域中几乎没有不同的有界上下文.CRUD操作的验证建立在每个有界上下文中.

例如,只有创建它的人是组长,我才能创建一个名为GAME的实体.

在这个例子中我有两个有界上下文(BC).一个是游戏BC,另一个是用户BC.为了解决这个问题,在游戏BC中,我必须在继续创建游戏之前向用户BC进行类似IsGroupLeader()的域服务调用.

我不认为DDD推荐这种类型的通信.我也可以在游戏BC中拥有一个用户实体,但我不想这样,因为同一个用户实体在不同的BC中的不同上下文中的使用方式不同.

我的问题是:

  1. 我是否应该使用域事件,其中游戏BC必须向用户BC发送事件以询问用户状态?使用这种方法,我不会像IsGroupLeader那样进行同步调用,而是进行名为is_group_leader的事件.然后游戏BC必须等待用户BC处理事件并返回状态.只有在用户BC处理事件之后,游戏BC才会创建游戏实体.

  2. CQRS是我问题的解决方案吗?

任何想法都赞赏.

eul*_*rfx 27

在集成BC时,您有几个选择.不鼓励呼叫外部BC的原因是因为它要求两个BC同时运行.然而,这通常是可以接受的并且比替代方案更简单.另一种方法是让游戏BC订阅来自用户BC的事件并保留其所需数据的本地副本,在这种情况下是关于用户是否是组长的信息.这样,当游戏BC需要确定用户是否是组长时,它不需要呼叫用户BC,它只是读取本地存储的数据.这种事件驱动的替代方案的挑战是同步事件.您必须确保游戏BC从用户BC接收所有适当的事件.另一个挑战是处理最终的一致性,因为在任何给定的时间点,BC可能会略微不同步.

CQRS与此问题有些正交.

  • 您无需捕获登录事件,您需要捕获发生更改为用户组长状态的事件.这通常在用户最初注册时和/或当存在将用户改变为或不远离组长的明确操作时发生. (4认同)

Rog*_*son 16

以下是我的理由.

我认为游戏BC不知道"用户",但它可能知道"玩家".

如果游戏BC依赖于活动/当前玩家,那么在创建游戏BC实例时它应该被传递到BC.

例如.

 Player currentPlayer = GetPlayerSomehow...();
 GameBC gameBC = new GameBC(currentPlayer);
 gameBC.DoStuff();
Run Code Online (Sandbox Code Playgroud)

现在您的两个BC仍然是分开的,您可以单独测试它们等.

为了使一切顺利,你只需做一些事情:

 User currentUser = GetCurrentUser();
 Player currentPlayer = new Player();
 currentPlayer.IsGroupLeader = currentUser.IsGroupLeader;
 GameBC gameBC = new GameBC(currentPlayer);
 gameBC.DoStuff();
Run Code Online (Sandbox Code Playgroud)

这可以作为UserBC和GameBC之间的反腐败层,您可以将您想要的状态从UserBC移动并验证到您的GameBC所需的状态.

如果您的GameBC需要访问许多用户,您仍然可以将某种地图服务传递到内部进行此类转换的BC游戏中.