发布实体状态变化的最佳实践

Best practice for publishing state changes of an entity

我有以下型号:

public class Team {
    public Guid Id {get; set;}
    public string Name {get; set;}
    public string League {get; get;}
    public int Rating {get; set;}
}

在系统中创建新团队后,我将事件:TeamCreated 发布到服务总线:

{
    "MessageId": "33909eaf-56a1-4467-a01a-64b94f10490c"
    "MessageType": "TeamCreated",
    "CreationDate": "20-01-2016",
    "Payload":  {
        "Id": "11111www-56a1-4467-a01a-64b94f000111",
        "Name": "Toronto Maple Leafs",
        "League": "NHL NorthEast",
        "Rating": 100
    }
}

下一步,因为此条目已修改为以下内容:

{
    "MessageId": "33909eaf-56a1-4467-a01a-64b94f10490c"
    "MessageType": "TeamUpdated",
    "CreationDate": "20-01-2016",
    "Payload":  {
        "Id": "11111www-56a1-4467-a01a-64b94f000111",
        "Name": "Toronto Maple Leafs",
        "League": "NHL NorthEast",
        "Rating": 50
    }
}

如您所见,他更新的消息仍然保留所有属性的值,而不仅仅是更改后的 属性,即团队评级。

我的模型在实际系统中有超过 50 个属性,我不想在更新时为每个 属性 创建单独的事件。特别是因为在一次更新中可能会更改多个 属性。

在事件溯源架构中是否有针对此场景的定义模式?

通常的答案是放弃 CRUD 事件,而是使用通用语言描述更改。

在某种程度上,这只是一种脱钩练习;我们正在尝试描述 "what happened" 而不会过多地关注我们今天碰巧实现实体状态的方式。

选择一个例子;假设“Leafs”要搬到维加斯;我们如何用无处不在的语言来描述它?我们可能会说球队 relocated(改变主场城市、体育场),realigned(改变联赛),并且可能 rebranded (更改球队名称、徽标),可能已出售(更改所有权组)。因此,我们不会将此数据打包到一个 TeamUpdated 事件中,而是希望看到表示为多个事件的变化,逻辑分组的数据共享适当的事件。

当您再水化实体时,它负责识别事件负载中的数据,并了解它如何更改自己的(私有)状态以反映之前记录的历史记录。