发布实体状态更改的最佳实践

时间:2016-08-18 12:29:11

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

我有以下型号:

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

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

1 个答案:

答案 0 :(得分:8)

通常的答案是放弃CRUD事件,而是使用普遍存在的语言来描述变化。

在某种程度上,这只是一种脱钩运动;我们试图描述"发生的事情"我们今天碰巧实施了实体的状态,而不是太过投入。

选择一个例子;假设“叶子”要搬到拉斯维加斯;我们如何用无处不在的语言描述它?我们可能会说团队重新定位(更改本地城市,体育场),重新签名(更改联盟),并且可能重新命名(更改团队名称) ,logo),可能出售(更改所有权组)。因此,我们不希望将此数据打包到一个TeamUpdated事件中,而是将更改表示为多个事件,逻辑分组的数据共享相应的事件。

当你为实体补充水分时,它负责识别事件有效载荷中的数据,并了解它如何改变它自己的(私人)状态以反映先前记录的历史。