简体   繁体   English

EventSourcing 和 DDD 实体事件

[英]EventSourcing and DDD Entity events

I have a DDD project using EventSourcing.我有一个使用 EventSourcing 的 DDD 项目。 And currently there are many aggregate roots many of which have collections of entities.目前有许多聚合根,其中许多都有实体的集合。 Even more - some entities have collections of other entities.甚至更多 - 一些实体具有其他实体的集合。

Problem: Reading EventSourcing event log for audit purposes.问题:出于审计目的读取 EventSourcing 事件日志。

Question: What is the best way to save events in EventStore when an entity is Updated/Created/Removed having all these things in mind: they have to be easily readable, versions, may be not for this case but usually granular events are preferable, probably domain-events are going to be used for cross domain communication.问题:当实体被更新/创建/删除时,在 EventStore 中保存事件的最佳方法是什么,记住所有这些事情:它们必须易于阅读,版本,可能不适合这种情况,但通常粒度事件更可取,可能域事件将用于跨域通信。

  1. Should I save in the root stream the whole root with all collections of entities inside as a RootChangedEvent ?我是否应该在根流中将整个根以及其中的所有实体集合保存为 RootChangedEvent ?

  2. Should I save only the entity which was Updated/Created/Removed in the root stream as a EntityChangedEvent/EntityCreatedEvent/EntityRemovedEvent我是否应该仅将根流中已更新/创建/删除的实体保存为 EntityChangedEvent/EntityCreatedEvent/EntityRemovedEvent

  3. Should I save in the root stream Two events - one for the root - RootChangedEvent with only the version property + second for the entity which will have only a single property if such changed in EntityChangedEvent or whole entity if EntityCreatedEvent or only id if EntityRemovedEvent (How to handle if entity of entity created/updated/removed?)我是否应该在根流中保存两个事件 - 一个用于根 - RootChangedEvent 只有版本属性 + 第二个用于实体,如果在 EntityChangedEvent 或整个实体中更改,则只有一个属性,如果 EntityCreatedEvent 或只有 id 如果 EntityRemovedEvent (如何处理实体的实体是否创建/更新/删除?)

Here is an example in my project:这是我项目中的一个例子:

The root - Pipeline.根 - 管道。

public class Pipeline : AggregateRoot<IPipelineState>

It has collection of entities - public IList<Status> Statuses .它具有实体集合 - public IList<Status> Statuses

And each Status has collection of entities - public IList<Logic> Logics .每个状态都有实体集合 - public IList<Logic> Logics

All collections could store a lot of entities.所有集合都可以存储很多实体。 And right now I raise events like PipelineCreatedEvent, PipelineChangedEvent (not only when Pipeline changed but even when adding, updating, removing Status or Logic) and PipelineRemovedEvent.现在我会引发诸如 PipelineCreatedEvent、PipelineChangedEvent(不仅在 Pipeline 更改时,甚至在添加、更新、删除状态或逻辑时)和 PipelineRemovedEvent 之类的事件。

There should be a single stream of events for any given aggregate, to avoid race conditions.任何给定的聚合都应该有一个事件流,以避免竞争条件。 Aggregate is a transaction boundary.聚合是一个事务边界。

In your case, try to formulate what happened in your system not in terms of Entities, but in business words:在您的情况下,尝试用商业术语而不是实体来表述系统中发生的事情:

  1. OrderCreated (orderId=123)订单创建 (orderId=123)
  2. OrderItemAdded (orderId=123, 'product1')添加订单项(订单 ID=123,'product1')
  3. OrderItemAdded (orderId=123, 'product2')添加订单项(订单 ID=123,'product2')
  4. OrderItemRemoved (orderId=123, 'product1') OrderItemRemoved (orderId=123, 'product1')
  5. OrderPaid (orderId=123)订单支付 (orderId=123)
  6. OrderArchived (orderId=123) OrderArchived (orderId=123)

These events happened with what?这些事件是怎么发生的? With Order so order is your aggregate root, and 123 - its aggregateId.使用 Order 所以 order 是您的聚合根,而 123 - 它的aggregateId。 You may not even need OrderItems there, unless this is required by command handler (say, you don't want to emit OrderItemRemoved event for already removed item).您甚至可能不需要 OrderItems ,除非命令处理程序需要这样做(例如,您不想为已删除的项目发出 OrderItemRemoved 事件)。

You will have a single event stream for aggregateRoot 123, and nobody can, say, add and OrderItem while you are processing PayOrder command.您将有一个用于aggregateRoot 123 的事件流,并且在您处理PayOrder 命令时,没有人可以添加和OrderItem。

It is important to understand that the more business specific your events, the more flexibility you'll have later with domain aggregates and read models.重要的是要了解,您的事件越具有特定的业务,您以后使用域聚合和读取模型的灵活性就越大。 Remember, your events are immutable and will be there forever!请记住,您的事件是不可变的,并且会永远存在!

OrderEntityChangedEvent (new Status = Paid) implies particular structure of your entities OrderPaid events assume nothing except there is an Order Aggregate root somewhere. OrderEntityChangedEvent (new Status = Paid) 意味着您的实体的特定结构OrderPaid事件假定除了某处有一个 Order Aggregate 根之外什么都不做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM