Domain driven design 如何确保应用命令的结果与应用事件的结果匹配

Domain driven design 如何确保应用命令的结果与应用事件的结果匹配,domain-driven-design,event-sourcing,Domain Driven Design,Event Sourcing,当我们使用所有事件(包括由Cx生成的事件)填充聚合时,执行命令Cx后聚合的状态Sx将是相同的,对于事件源,我们有什么把握 例如: 命令Cx到达并影响聚合w 我们查询与聚合w关联的所有事件(E1,E2..Ex-1),并构建其状态到该点,获得Sx-1 我们将Cx应用于Sx-1,我们获得Sx,并发出将被存储的事件Ex 我如何知道由命令生成的Sx相当于由事件E1,E2..Ex生成的Sx。 假设从事件生成聚合的代码与处理命令的代码不同,则两个聚合之间可能不匹配。通常的答案是,Sx是通过将Ex应用到Sx-

当我们使用所有事件(包括由
Cx
生成的事件)填充聚合时,执行命令
Cx
后聚合的状态
Sx
将是相同的,对于事件源,我们有什么把握

例如:

  • 命令
    Cx
    到达并影响聚合
    w
  • 我们查询与聚合
    w
    关联的所有事件(
    E1,E2..Ex-1
    ),并构建其状态到该点,获得
    Sx-1
  • 我们将
    Cx
    应用于
    Sx-1
    ,我们获得
    Sx
    ,并发出将被存储的事件
    Ex
  • 我如何知道由命令生成的
    Sx
    相当于由事件
    E1,E2..Ex
    生成的
    Sx

    假设从事件生成聚合的代码与处理命令的代码不同,则两个聚合之间可能不匹配。

    通常的答案是,
    Sx
    是通过将
    Ex
    应用到
    Sx-1

    Sx-1 <- [E1..Ex-1]
    Ex <- (Cx, Sx-1)
    Sx <- (Sx-1, Ex) === ([E1..Ex-1], Ex) === ([E1..Ex])
    
    Sx-1
    我们将Cx应用于Sx-1,获得Sx并发出一个将被存储的事件Ex

    这并不完全正确

    处理命令时,应用程序服务调用聚合的方法:

    var aggregate = store.Load<MyAggregate>(cmd.Id);
    aggregate.DoWorkWhatever(cmd.OneField, cmd.TwoField);
    
    Apply
    方法调用聚合的某些部分以更改其状态:

    When<DidWorkWhatever>((state, x) => { state.One = x.One, state.Two = x.Two });
    
    When((state,x)=>{state.One=x.One,state.Two=x.Two});
    
    最后,您将获得具有更新状态和触发状态转换的事件的聚合。因此,应用程序服务可以通过提交新事件来保持聚合状态


    也许能帮上忙。

    让我澄清一下,看看我是否理解正确。在接收到
    Cx
    后,我生成
    Ex
    ,然后将其应用于
    Sx-1
    。因此,事件并未真正发生。你不觉得奇怪吗?这是一个不是事件的事件。
    When<DidWorkWhatever>((state, x) => { state.One = x.One, state.Two = x.Two });