DDD - 在其他有界上下文中验证实体的存在

DDD - Validation for existence of entity in other bounded contexts

我有一个问题,即在验证实体是否存在于有界上下文中时,最佳做法是什么。这甚至是 DDD 中的有效方法吗? BC 本质上应该是独立的部署(即你不应该依赖另一个可能不可用的 BC)。

我的项目中有 2 个 BC - 配料和食谱。该企业销售散装原料,但也销售使用所述原料的预配置食谱。现在这些都是独立的 BC,每个都有自己的成分实体。

Recipe 是一个聚合根,它有一个成分列表的子实体。在将一种成分添加到 Recipe BC 中的成分列表之前验证 Ingredient BC 中是否存在这种成分是否有意义?

只能通过将发布事件的成分 BC 修改成分,并且食谱 BC 将订阅并更新其自己的成分以进行任何更改(即 price/name)。为了使其有效,成分需要是有效的。那么如何保持这些 BC 之间的一致性呢?我是否将域服务注入到配方 BC 中并在添加它们之前验证成分是否存在?我也在使用 CQRS,所以我可以将服务直接注入处理程序而不是用于创建食谱的工厂(或者这是使用域服务的正确方法吗?)。

对此有点迷茫,如果这是一个有效的问题。

一般来说,你的食谱应该只关心成分的唯一标识符,而不是它的细节。配方的一致性不需要成分的详细信息。

我假设某些操作(例如用户与 UI 交互)会向食谱中添加成分。我还假设可以添加的成分来自仅 returns 有效成分的查询。除非您有理由担心 something/someone 会破坏此过程,否则您可能会花时间解决不太可能成为真正问题的问题。

如果这实际上是一个真正的问题,那么是的,您可以在添加之前验证这些成分是否存在。但是,这可能最好在命令验证器中靠近 Recipe BC 的边界完成。

限界上下文是概念性的——它(通常)不由单个 class 表示。我提到这个是因为你问

Do I inject a domain service into the recipe BC . . . ?

你并不是真的 "inject" BC。同样,如果您 需要此验证,您可能会有一个验证 class 通过 API 或数据库查询成分 BC 以确保它存在。

the recipe BC will subscribe and update its own ingredients for any changes (i.e. price/name).

这应该没有必要。配方有其每种配料的引用,因此当您查询配方时,您会查询配料列表和这些配料的详细信息。根据您的设置,这可能是 SQL 加入或其他方式(根据您的设置,可以通过多种不同的方式完成此操作)。您通常应该避免在收据 BC 中缓存成分详细信息,除非您对性能有特定的担忧。缓存总是会增加复杂性。

当您继续使用 CQRS 时,您会发现很多您通常认为 "Command Problems" 的问题实际上在查询端更容易解决。

感觉你BC的界限是错误的。尝试找出他们为您的企业执行的业务能力。不要将实体的名称与限界上下文的名称一对一映射。在聚合之间,您无法保证跨国一致性。即使你检查了你的成分,它也可能在那里,但在 1 毫秒后它就消失了,你将继续执行你的逻辑,认为它在那里。我不明白为什么 Ingredient 应该是一个单独的 BC 和 Recipe。它有什么价值。