1

我读到 CQRS 中的命令被设计为不会失败,并且本质上应该是异步的。

就我而言,我有一棵树(想想 Windows 资源管理器),其中用户有代表视频内容位置的文件夹,每个子节点都是一个视频/媒体文件。多个用户都可以在树的同一分支上移动文件夹和文件(并上传新文件和创建新文件夹以及删除文件/文件夹)。

如果我忽略了命令的异步性质,我可以让第一个用户进行更改并在第二个用户提出异常,如果说用户将视频移动到的文件夹不再存在。现在第二个用户有责任刷新他的树的一部分,然后重新应用他的更改。

如果我的更改未被允许(即我尝试将视频文件移动到另一个文件夹并且另一个用户已删除该文件夹或将其移至其他位置),我将如何使用 CQRS 执行此操作?

4

1 回答 1

1

当您将命令发送到您的域时,您的命令应该是有效的。因此,在发送之前,您必须在客户端上验证它以了解该文件夹是否仍然存在。它允许您通过清晰的错误消息告诉客户到底发生了什么

这也减少了很多错误的余地。发生故障的时间范围减少到通过网络发送命令的时间和在服务器上执行命令的时间。

  • 如果这个风险真的很低。我们可能只收到来自域的失败命令答案(例如:枚举)。对于用户来说,它可能会以一般的异常消息告终,我们可以实现它的数据以向他展示事情是不同的,并且他不能做他想做的事情。我预计,如果此类消息在一年中仅出现 2-3 次,那么百分比较低的消息应该不会是一个大问题。

  • 如果这种风险真的很高,或者如果无法从客户端进行验证,但只能在域端进行,那么我目前无法给你答案。我自己正在学习 CQRS,我不能说更多。

希望它有所帮助,

[编辑]

我假设命令处理不是异步的。如果是这样,我会尝试在命令执行期间捕获任何异常,并且我可以返回一些失败通知,而无需向客户端说明它到底是什么。对各种 readmodel 的投影保持异步。

 public void Handle(ICommand command)
        {
            try
            {
                CommandService.Execute(command);

                Bus.Return(ErrorCodes.None);
            }
            catch (Exception e)
            {
                Bus.Return(ErrorCodes.Fail);
            }
        }

我的 CommandServiceDelegate 正确的执行者来完成这项工作:

Public class TheGoodExecutor{
      protected void Execute(IUOW context, MyCommand command)
        {
            var myDomainObject= context.GetById<DomainObjecType>(command.Id);

            myDomainObject.DoStuff(Command.Data);

            // Accept all the work we just did.
            context.Accept();
        }
}

如果好的 Executor 出错,那么 Bus.Return(ErrorCodes.Fail);

这可以由我的客户同步或异步接收。

如果您希望完全异步(这就是我正在尝试做的事情,或者至少我想以这种方式进行探索),我会尝试订阅事件,客户可能会感兴趣。我认为对于验证,听在大多数情况下,事件没有多大意义。但在第二种情况下,我说的是,它可能。在其他情况下,除了验证,它也可能......

斜体中的所有内容都是一些个人试用,我没有读过任何关于它的东西,也没有完成任何在这个意义上正常工作的东西。所以用大括号.. he he!!

[/编辑]

于 2012-04-12T09:53:53.427 回答