【问题标题】:CQRS - When a command cannot resolve to a domainCQRS - 当命令无法解析到域时
【发布时间】:2012-07-18 04:05:59
【问题描述】:

我正试图围绕 CQRS。我从here 提供的代码示例中提取。请温柔,我对这种模式很陌生。

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

在 fohjin 示例中,事件总是从域中触发(如果需要),并且命令处理程序调用域上的某些方法。但是,如果用户登录无效,我就没有域可以调用任何东西。此外,fohjin 项目中定义的大多数(如果不是全部)基本命令/事件类都传递一个聚合 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();
    }

【问题讨论】:

  • 我在 CQRS+ES 上写了一个 MembershipProvider,如果你 want to take a look,这是我的尝试之一
  • 感谢帮助。它似乎忽略了与现有用户名不匹配的登录尝试的记录。这是我问题的核心
  • 失败的尝试存储在 Faliedpassword 尝试和 FailedPasswordQuestionAndAnswerAttempt 和相对日期时间中

标签: cqrs


【解决方案1】:

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

要记住的另一件事是,由于最终的一致性,我们只使用查询端进行尽可能多的检查是非常有益的,而事件不会创建任何命令/事件。

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

  1. 用户提供名称和密码
  2. 名称/密码已针对某种查询数据库进行验证
  3. 当提供的凭据有效时,RegisterValidUserCommand(userId) 被执行,这会导致正确的事件
  4. 如果提供的凭据无效 执行 RegisterInvalidCredentialsCommand(providedUserName) 会导致正确的事件

关键是检查用户凭据不一定是业务领域的一部分。

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

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

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

【讨论】:

  • 同意。虽然域内用户的访问可能是您想要建模的东西。
  • 所以您的建议是避免查询命令中的写入存储以外的任何内容?我认为我需要一个单独的抽象/事件存储来存储不针对特定聚合的事件(因为我仍然希望通过事件溯源来重现失败)。我认为这个登录场景最适合你的第二个例子,它对实体没有意义。我只是对在哪里进行身份验证检查感到困惑。感谢您的回复。
  • 使用 cqrs 建模的另一个问题是在命令和/或事件中记录明文密码
猜你喜欢
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
  • 2014-06-13
  • 1970-01-01
相关资源
最近更新 更多