C# 应该使用方法参数还是通过引用将命令信息传递给聚合?

C# 应该使用方法参数还是通过引用将命令信息传递给聚合?,c#,.net,cqrs,event-sourcing,C#,.net,Cqrs,Event Sourcing,我正在致力于实现一个基本的CQRS+ES应用程序。我看过很多例子,但我不了解命令处理程序和聚合之间的路由 在一些例子中,工作是这样做的: XCommandHandler: void Handle(XCommand command) { var aggregate = this.repository.Find<Aggregate>(command.aggId); aggregate.InvokeSomeBusinessLogic(command.property1, co

我正在致力于实现一个基本的CQRS+ES应用程序。我看过很多例子,但我不了解命令处理程序和聚合之间的路由

在一些例子中,工作是这样做的:

XCommandHandler:

void Handle(XCommand command) {
   var aggregate = this.repository.Find<Aggregate>(command.aggId);

   aggregate.InvokeSomeBusinessLogic(command.property1, command.property2);
   this.repository.Save(aggregate);
}
void Handle(XCommand command) {
   var aggregate = this.repository.Find<Aggregate>(command.aggId);

   aggregate.InvokeSomeBusinessLogic(command);
   this.repository.Save(aggregate);
}
void句柄(XCommand命令){
var aggregate=this.repository.Find(command.aggId);
InvokeSomeBusinessLogic(command.property1,command.property2);
this.repository.Save(聚合);
}
但其他人则以另一种方式:

XCommandHandler:

void Handle(XCommand command) {
   var aggregate = this.repository.Find<Aggregate>(command.aggId);

   aggregate.InvokeSomeBusinessLogic(command.property1, command.property2);
   this.repository.Save(aggregate);
}
void Handle(XCommand command) {
   var aggregate = this.repository.Find<Aggregate>(command.aggId);

   aggregate.InvokeSomeBusinessLogic(command);
   this.repository.Save(aggregate);
}
void句柄(XCommand命令){
var aggregate=this.repository.Find(command.aggId);
InvokeSomeBusinessLogic(命令);
this.repository.Save(聚合);
}

最好的方法是什么,尤其是当一个命令中有许多属性(15个或更多)时?

这不是一个关于CQRS+ES的问题,而是一个关于API总体设计的问题。正如所解释的,没有参数的方法比有一个参数的方法好,这比有两个参数的方法好,等等

盲目地遵循这一规则应该总是让你选择第二个选项:

aggregate.InvokeSomeBusinessLogic(command);
然而,盲目地遵循任何规则很少是一个好主意。在这种情况下,考虑反作用力是一个好主意:

客户机不应该被迫依赖于他们不使用的方法

因为getter和setter也是方法,所以我认为这个原则也适用于命令对象

因此,如果您有15个或更多属性,但所讨论的方法只需要其中两个,那么最好只传递这两个值

另一件事是,如果您有一个具有15个属性的命令对象,您可能需要重新考虑您的设计。CQRS+ES背后的一个基本假设是存在应用程序,这确保每个命令(以及相应的事件)都是“小”的


正在使用链接编辑Mark的评论,因为其中一个链接已断开:


更新聚合信息不是基于任务的;是积垢。也许Udi Dahan的这两篇文章会有所帮助


原则上我同意马克的观点。然而,我要指出,CQR是从领域驱动的设计世界发展而来的。他们强调语言的重要性()。您可以捕获命令对象的实际名称中的意图和意义

在实际层面上,如果从多个地方调用,通过添加参数的重构方法可能会成为一个真正的难题。使用单个对象可以显著缓解这一问题

我有几个相关的帖子,你可能会觉得有用。和。虽然最后一个是关于事件的,但许多原则都适用


希望对您有所帮助。

谢谢Mark,但是如果UI任务与更新聚合信息相关,UI将捕获聚合主信息,并将其放入总线(或通道,如您的CQRS示例),因此我有一个命令,其中包含与同一任务相关的15个属性,请更新聚合。我应该把这个逻辑分成更多的小命令?或者使用包含所有数据的更新命令是否有效?更新聚合信息不是基于任务的;是积垢。也许Udi Dahan的这两篇文章会有所帮助。完美的我得到了它!我以一种错误的方式对域模型进行建模,我将以一种新的方式进行建模。谢谢,我按照Mark的建议对代码进行了重构,代码现在更易于维护。