0

我们在我们的应用程序中使用事件溯源,并且严格需要跟踪对我们的许多对象发起更改的用户。目前我们有这样的代码

class Order { 
  setNameBy(newname, User user) {
    applyChange(new OrderRenamed(user.id, newname));
  }
  :
}

由于我们的大多数方法都是这样的,而且所有的方法都是这样调用的

setNameBy("a new name", SessionContext.currentUser)

我们正在考虑访问域对象内的 SessionContext。IE:

setNameBy(newname, User user) {
  applyChange(new OrderRenamed(user.id, newname));
}

变成

setName(newname) {
  applyChange(new OrderRenamed(SessionContext.currenUser.id, newname));
}

我个人更喜欢后面的方法签名,因为它接缝更自然,另一方面,访问 Domain 对象内的 SessionContext 感觉有点混乱。

那么如何在 DDD/CQRS 应用程序中最好地处理这样的会话数据?是否可以访问域对象中的 SessionContext 或者我应该使用其他方法(如事件丰富)将此信息添加到从域发出的事件中?

4

2 回答 2

2

我更喜欢让我的领域模型完全不了解外部细节。如果您的域对象需要用户 ID 来执行业务规则,我将使用您当前的方法并将用户作为参数发送。如果您只需要用户 ID 用于跟踪/审核目的,您可以丰富事件。

于 2012-04-11T04:59:52.340 回答
2

如果跟踪发起更改的用户频繁发生,则 SessionContext 成为解决方案的固有部分,因此 IMO 成为阻力最小的路径(足够好的解决方案)。也许对 UserContext 的改写会使它听起来不像是“肮脏”的技术耦合?:)

我经常在我的应用程序中使用线程绑定上下文(包括事件源和非事件源),如果 SessionContext.currentUser 抛出异常以防 SessionContext 未绑定到线程,那么它还可以帮助在测试期间发现错误(至少对我来说是这样)。

另一种方法可以是将事件标记为需要用户跟踪(例如,使用界面),然后再丰富事件。这对我来说有点麻烦,并且可能会使问题解决变得更加困难,因为未绑定的 SessionContext 异常将发生在需要用户信息的业务功能之外。

这两种解决方案都是 IMO 足够好的解决方案,因此主要取决于您希望在何处耦合到 SessionContext。

于 2012-04-11T06:11:39.093 回答