我们在应用程序中使用事件采购,并且还严格需要跟踪对我们的许多对象进行更改的用户。目前我们有这样的代码
class Order {
setNameBy(newname, User user) {
applyChange(new OrderRenamed(user.id, newname));
}
:
}
由于我们的大多数方法都是这样的,并且所有方法都像这样被调用
setNameBy("a new name", SessionContext.currentUser)
我们考虑访问域对象内的SessionContext。即:
setNameBy(newname, User user) {
applyChange(new OrderRenamed(user.id, newname));
}
变为
setName(newname) {
applyChange(new OrderRenamed(SessionContext.currenUser.id, newname));
}
我个人更喜欢后面的方法签名,因为它接缝更自然,另一方面,访问Domain对象内的SessionContext会感觉有些麻烦。
那么如何在DDD / CQRS应用程序中最好地处理这样的会话数据?是否可以访问Domain对象中的SessionContext,还是应该使用其他方法(如事件丰富)将此信息添加到域中发出的事件中?
答案 0 :(得分:2)
我更喜欢让我的域名模型完全不了解外部细节。如果您的域对象需要用户ID来强制执行业务规则,我将使用您当前的方法并将User作为参数发送。如果您只需要用户ID进行跟踪/审核,则可以丰富事件。
答案 1 :(得分:2)
如果经常跟踪发起更改的用户,则SessionContext成为解决方案的固有部分,因此IMO成为阻力最小的路径(足够好的解决方案)。也许对UserContext的重写将使它听起来不像是一个“脏”的技术耦合? :)
我经常在我的应用程序中使用线程绑定上下文(事件源和非源),如果SessionContext.currentUser在SessionContext尚未绑定到线程的情况下抛出异常,那么它也可以帮助发现bug在测试期间(至少它对我而言)。
替代方案可以是将事件标记为需要用户跟踪(例如使用界面),然后再丰富事件。这对我来说感觉有点麻烦,并且可能更难以解决问题,因为在需要用户信息的业务功能之外会发生未绑定的SessionContext异常。
这两个解决方案都是IMO足够好的解决方案,所以这主要取决于您希望与SessionContext耦合的位置。