CQRS - 当命令无法解析到域时

时间:2012-07-18 04:05:59

标签: cqrs

我正试图围绕CQRS。我是从提供here的代码示例中提取的。请保持温和,我对这种模式很新。

我正在查看登录方案。我喜欢这种情况,因为在我读过的任何例子中都没有真正证明这一点。在这种情况下,我不知道用户的聚合ID是什么,或者即使有一个,因为我开始使用的是用户名和密码。

在fohjin示例中,事件始终从域中触发(如果需要),并且命令处理程序在域上调用某些方法。但是,如果用户登录无效,则我没有域可以调用任何内容。此外,大多数(如果不是全部)fohjin项目中定义的基本Command / Event类都会传递聚合ID。

对于LogonFailure事件,我可能想要更新LogonAudit报告。

所以我的问题是:如何处理不能解析为特定聚合的命令?那会怎么样?

    public void Execute(UserLogonCommand command)
    {
        var user = null;//user looked up by username somehow, should i query the report database to resolve the username to an id?

        if (user == null || user.Password != command.Password)
            ;//What to do here? I want to raise an event somehow that doesn't target a specific user
        else
            user.LogonSuccessful();
    }

1 个答案:

答案 0 :(得分:3)

您应该考虑到大多数情况下CQRS和DDD仅适用于系统的某些部分。使用CQRS概念对整个系统进行建模非常罕见 - 它最适合具有复杂业务领域的部分,我不会在特别复杂的业务场景中调用日志记录用户。事实上,在大多数情况下,它根本不与业务有关。当用户已被识别时,实际业务域开始。

另一件需要记住的事情是,由于最终的一致性,在没有事件创建任何命令/事件的情况下,尽可能多地使用查询端进行检查是非常有益的。

但是,假设有关成功/失败用户登录的信息是有意义的,我将使用以下步骤为您的方案建模

  1. 用户提供姓名和密码
  2. 根据某种查询数据库验证名称/密码
  3. 提供的凭据有效时执行RegisterValidUserCommand(userId)会导致正确的事件
  4. 如果提供的凭据无效 执行RegisterInvalidCredentialsCommand(providedUserName)导致正确的事件
  5. 重点是检查用户凭据不一定是业务域的一部分。

    也就是说,还有另一个相关概念,其中并非每个命令或事件都需要与业务相关,因此可以处理不需要加载聚合的事件。

    例如,您希望更改仅供参考的数据,而不会影响系统的业务概念,例如有关人的性别的信息(再次假设它没有商业意义)。

    在这种情况下,当您处理SetPersonSexCommand时,实际上不需要加载聚合,因为该信息甚至不必位于实体上,而是创建PersonSexSetEvent,注册它并发布,以便查询端可以将其投影到屏幕/ raport。