【问题标题】:Best practice for publishing state changes of an entity发布实体状态更改的最佳实践
【发布时间】:2023-03-14 05:46:01
【问题描述】:

我有以下型号:

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 多个属性,我不想在更新每个属性时为其创建单独的事件。特别是因为在一次更新中可能会更改多个属性。

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

【问题讨论】:

    标签: domain-driven-design cqrs event-sourcing


    【解决方案1】:

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

    在某种程度上,这只是一个解耦练习;我们试图描述“发生了什么”,而不是过多地投入到我们今天碰巧实现实体状态的方式上。

    选择一个例子;假设叶子要搬到维加斯;我们将如何用无处不在的语言来描述它?我们可能会说球队搬迁(改变家乡城市、体育场),重新调整(改变联赛),并且可能重新命名(改变球队名称, 徽标),可能已售出(更改所有权组)。因此,与其将这些数据打包到一个 TeamUpdated 事件中,我们希望看到更改表示为多个事件,逻辑分组的数据共享适当的事件。

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

    【讨论】:

    • 解释得很好。
    • 对此+1。如果您有超过 50 个属性会发生 ThingUpdated 事件,那么您绝对需要将其拆分为已发生的域事件
    猜你喜欢
    • 2014-02-20
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    相关资源
    最近更新 更多