2

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

我正在查看登录方案。我喜欢这种情况,因为在我读过的任何示例中都没有真正体现出来。在这种情况下,我不知道用户的聚合 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();
    }
4

1 回答 1

3

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

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

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

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

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

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

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

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

于 2012-07-19T13:32:25.800 回答