6

我的问题与 CQRS(命令和查询责任分离)和构建读取模型(视图)的机制有关。据我了解,读取模型是由事件处理程序构建的。这些处理程序(也称为非规范化程序)接收域事件并使用这些事件来构建不同的数据视图。

特定事件携带有关在域模型中完成的更改的信息。我认为在某些情况下,此信息不足以构建视图 - 即未更改的字段,未更改的实体在此类事件中丢失等。

所以我的问题是:

是否允许负责构建读取模型的非规范化程序不仅访问事件,还访问:

  1. 事件中直接引用的更改实体?
  2. 更改了聚合根以及与此聚合相关的任何实体?
  3. 从存储库中获取的任何实体?
  4. 有什么看法吗?

您对事件处理程序(非规范化程序)允许的依赖项有何看法?

编辑:刚刚在上面的问题中添加了简单的例子:

假设以下模型:

AR:ProductOffering * 名称 * 描述 * 类别 * 价格

AR: Customer * name * type * method: purchaseProduct(productOffering) 发出 ProductPurchasedByCustomer 事件

实体:ProductInstance * customer * productOffing

事件:ProductPurchasedByCustomer * customerId * productOfferingId

视图:ProductInventoryView * customerId * productOfferingId * customerType * productOfferingName * productOfferingCategory * price

如何仅使用 ProductPurchasedByCustomer 事件构建 ProductInventoryView?如何编写非规范化程序以查看有关 customerType、productOfferingName 等的信息?我应该从不同的视图中查找有关 customerType 和 productOfferingName 的其他信息吗?

4

2 回答 2

8

如果事件消费者需要更多信息,事件生产者可以提供所需的信息,即使它没有改变。Eventsourcing 不应被视为 ORM。请注意,关于您如何获取该信息,事情可能会变得棘手,但不要让事情复杂化(还)。如果事件未提供读取模型的状态(数据),则事件处理程序可以使用它。但是这样做需要您知道是否可以使用以及可以使用哪些数据。它需要您将时间与数据结合起来。消息/事件可能会乱序处理。因此,在事件中提供与事件相关的信息要容易得多。在做任何其他事情之前尝试这样做。不要尝试从特定于您的读取模型的事件处理程序访问您的域,这只是令人讨厌的耦合。最后一件事,它' 聚合可以从其他聚合复制数据以提供您在事件中需要的数据。请注意,从那时起,您将不得不开始考虑如何在最初复制它的聚合中保持数据的新鲜度。可能让你更困惑了......

于 2010-12-19T00:55:01.827 回答
0

根据我的理解:

事件中直接引用的更改实体?

更改了聚合根以及与此聚合相关的任何实体?

从域存储库中获取的任何实体?

任何与事件无关的报告

事件中直接引用的实体的更改实体报告?

是的

更改了聚合根报告以及与事件中引用的聚合相关的任何实体报告?

是的


因为 denormalizer 应该对域存储库一无所知,只更新相关报告。

如果报告似乎不相关但必须更新,那是代码异味 - 可能您设计的模型/报告不正确。

于 2010-12-13T12:37:53.127 回答