Oop 在ICommandExecutor.Execute()方法中返回结果好吗?

Oop 在ICommandExecutor.Execute()方法中返回结果好吗?,oop,cqrs,Oop,Cqrs,我对CQRS中指挥部分的设计有一些想法。我想听听你对我想法的看法。提前感谢!:) 在CQR中,有命令和命令执行器。有时,我们希望命令执行者在执行完成后返回一些结果。一种可能的解决方案是(C#): 公共接口ICommandExecutor { 无效执行(TCommand cmd); } 公共接口ICommandExecutor { TResult Execute(TCommand cmd); } 到目前为止还不错。我们使用两个命令执行器接口。现在让我们看看客户端代码: var cmd = new

我对CQRS中指挥部分的设计有一些想法。我想听听你对我想法的看法。提前感谢!:)

在CQR中,有命令和命令执行器。有时,我们希望命令执行者在执行完成后返回一些结果。一种可能的解决方案是(C#):

公共接口ICommandExecutor
{
无效执行(TCommand cmd);
}
公共接口ICommandExecutor
{
TResult Execute(TCommand cmd);
}
到目前为止还不错。我们使用两个命令执行器接口。现在让我们看看客户端代码:

var cmd = new MyCommand();
commandBus.Execute(cmd);  // execute no result
commandBus.Execute<MyResult>(cmd); // execute result
var cmd=new MyCommand();
commandBus.Execute(cmd);//无果而终
commandBus.Execute(cmd);//执行结果
是的,我们现在可以让executor返回结果。但是程序员在编写上面的代码时可能会感到困惑:这个命令是否可以作为结果执行??为了得到答案,程序员需要查看框架源代码,看看是否有MyCommandExecutor或MyCommandExecutor。这太糟糕了!非常混乱

因此,在我看来,我们应该删除ICommandExecutor。 也就是说,我认为命令执行者应该总是返回void。
ICommandExecutor
的设计不好

如果我们需要查看命令执行后发生了什么变化。我们应该在调用commandBus.Execute(cmd)之后对数据库进行新的查询


您对此有何看法?

严格来说,如果您使用的是命令模式,它不应该返回任何内容,但应该始终是
void
。您应该使用另一个命令(查询)来获取任何数据


您不应该添加第二个接口。我不确定返回值是否适用于CQR中的命令,但我有时会使用我的命令执行此操作(但我不遵循CQR)。但是,不要使用第二个接口,而是向命令添加输出属性

public class CreateCustomerCommand
{
    // customer properties here

    // output property
    public Guid CustomerId { get; internal set; }
}
但请记住,具有输出属性的命令永远无法异步运行

如果您真的希望有一个带有返回值的executor接口(这是我不建议的),请查看。这篇文章是关于以可靠的方式实现查询的,但它处理的是定义一个类型安全接口的问题,该接口允许您返回数据


顺便说一句,在前面的示例中,通过将
CustomerId
属性设置为输入属性,可以轻松地使命令异步。您可以让客户端提供一个新的随机Guid。这样,客户端已经有了可用的ID,不必等待结果变为可用。

在CQRS中,命令端不应返回任何内容,因为它破坏了模式的解剖结构。你自己的想法是正确的

然而,Greg Young经常提到命令操作的Ack/Nack结果(或者习惯于)。大多数消息传递框架都支持这种响应。期望结果的缺点是不能完全异步。我从来没有觉得需要Ack/Nack,因为CQRS的基本原理之一是命令应该总是成功的,所以返回Ack/Nack没有意义

问问自己你需要什么回报。什么操作需要返回您在发送/命令端还没有的信息?在让命令变成查询之前,花点时间弄清楚这一点。

您应该使用a来获取数据。“输出属性”是一个非常好的解决方案。谢谢顺便说一句:我也是一名自由职业者;)
public class CreateCustomerCommand
{
    // customer properties here

    // output property
    public Guid CustomerId { get; internal set; }
}