DDDD:事件数据
Posted
技术标签:
【中文标题】DDDD:事件数据【英文标题】:DDDD: Event data 【发布时间】:2013-04-16 14:48:01 【问题描述】:我正试图以 Greg Young 的风格了解 DDDD。
关于如何使用 CQRS+EventSourcing 实现 DDDD 有很多讨论,并且有一些示例实现......总之它可能会让人很困惑......
在 Gregs 视图中,聚合没有 getter 或 setter - 只是发出相应事件的状态更改方法。
基本上,事件描述了过去发生的状态转换。它的数据描述了发生了什么变化。
有人说,这些数据可以通过其他数据“丰富”。在哪里这些额外的数据可以来自吗?
即我有 User
和 Usergroup
- 两个聚合根(可以独立存在,有身份)。 User
有一个名为 AddToUsergroup
的方法。
public class User : AggregateRoot
// ...
public void AddToUsergroup(Usergroup usergroup)
// validate state
RaiseEvent(new UserJoinedUsergroup(this.Id, usergroup.Id));
// ...
public class Usergroup : AggregateRoot
private string _displayName;
// ...
public void ChangeDisplayName(string displayName)
// validate state
RaiseEvent(new DisplayNameChanged(this.Id, displayName));
public void Apply(DisplayNameChanged e)
this._displayName = e.DisplayName;
// ...
如果我想用用户组名称“丰富”事件(出于调试原因或类似原因),我该怎么做?
getter不存在 用户组的内部状态是不可访问向User
注入诸如存储库之类的东西是不允许(我在这里吗?!?), 像
底线问题:
而且(有点离题,但示例在这里)
应该AddToUsergroup
采用Guid 而不是 完整 聚合根?
期待您的回答!
Lg 瓦拉帕
【问题讨论】:
我可以帮你解决题外话问题。你应该只将 Guid 传递给方法,而不是聚合根。 关于“底线问题”。在我的使用中,事件应该包含业务案例所需的最少信息量。它应该只包含来自聚合本身的数据。即:通过参数或内部状态传递。 @Sarmaad 谢谢!你加强了我的假设! 【参考方案1】:是否应该注入存储库之类的东西来聚合根?
不,在这种情况下也没有必要。将域服务传递给聚合上的行为方法可能是合适的,但同样在这种情况下不需要。
一个事件是否应该只使用通过参数和内部可用的数据? 聚合的状态?
是的,原始域事件应该可以很容易地由聚合构建,并且可以以确定性的方式重放。
事件是否应该只包含描述事件的最少数据? 状态变化?
是的。然而,为了满足外部订阅者的需求,这就是content enricher 发挥作用的地方。要从外部分派域事件,首先将其提交到事件存储,然后您可以在同一个 tx 中分派或使用进程外机制将事件发布到外部。在外部发布时,您通常会为消息使用不同的合同,因为订阅者可能需要的不仅仅是域事件本身的内容。在这种情况下,您需要用户组名称。然后,发布者可以提取用户组名称并将该数据放入丰富的事件中。此发布者可以访问用户组的读取模型存储库,这将允许它检索名称。
AddToUsergroup 是否应该采用 Guid 而不是完整的聚合根?
是的。传递整个聚合可能是不可能的,而且还会产生一种错觉,即可以使用 ID 以外的东西,但事实并非如此。
【讨论】:
感谢您的解释,尤其是对内容丰富器的澄清!以上是关于DDDD:事件数据的主要内容,如果未能解决你的问题,请参考以下文章