C# Greg Young的服务宗旨';s CQRS实现

C# Greg Young的服务宗旨';s CQRS实现,c#,domain-driven-design,cqrs,C#,Domain Driven Design,Cqrs,我决定在以下示例中熟悉一个具体的CQRS实现: 我不明白的是,这里的服务是什么意思,因为它似乎与我们过去常用的三层模式完全不同 客户端更改接收到的DTO,并创建一个命令,该命令由调用域对象方法的处理程序处理 然后,事件被创建并存储在事件存储中,并发布以同步非规范化部分 我在这家连锁店找不到服务 我的同事告诉我,例如,如果我们不想在存储报表时将大数据存储为域的一部分,但当我们需要它时,我们会发布一个事件,该事件会从服务返回一些内容 但我无法清楚地在脑海中形成这幅画面 有人能解释一下服务应该做什么吗

我决定在以下示例中熟悉一个具体的CQRS实现:

我不明白的是,这里的服务是什么意思,因为它似乎与我们过去常用的三层模式完全不同

客户端更改接收到的DTO,并创建一个命令,该命令由调用域对象方法的处理程序处理

然后,事件被创建并存储在事件存储中,并发布以同步非规范化部分

我在这家连锁店找不到服务

我的同事告诉我,例如,如果我们不想在存储报表时将大数据存储为域的一部分,但当我们需要它时,我们会发布一个事件,该事件会从服务返回一些内容

但我无法清楚地在脑海中形成这幅画面


有人能解释一下服务应该做什么吗?

“服务”可以代表不同的东西,具体取决于您所谈论的上下文。在阅读这篇文章时,我相信他使用的是“服务”一词


但是,在CQR中,通常有命令服务查询服务,它们在DDD上下文中表示应用程序服务层。但正如我所说,在阅读这篇文章时,我认为他使用的“服务”一词是指域服务。

你指的是服务一个远程门面(Web服务),它将调用应用层,因为域服务是另一回事

远程外观层(web服务)如果您正在设计n层应用程序以向其他层公开应用程序服务,则将通过调用应用程序层(David提到的应用程序层)来公开您的业务和命令:

对于Read部分,在应用程序层中,您需要设计一个查询服务,其方法类似于
FindOrders(x,y,z)
GetMostOrderedItems()

对于写入部分,您可以通过以下多种方式之一设计命令服务:

  • 接受DTO并基于其执行域逻辑的服务[最小CQR]:
public void ActivateOrder(intorderId)
{
var order=\u orderRepository.FindOrder(orderID);
order.Activate();
}
public void UpdateClientAddress(客户端地址到地址)
{
var client=\u clientRepository.FindClient(address.ClientID);
client.Address=/…将ClientAddressDTO映射到地址
}
  • 获取DTO并将其转换为要在域模型上执行的命令的服务:
public void ActivateOrder(intorderId)
{
var orderActivationCommand=新的orderActivationCommand(orderID);
_commandExecuter.Execute(orderActivationCommand);
}
public void UpdateClientAddress(客户端地址到地址)
{
var clientMovingCommand=新的clientMovingCommand(address.ClientID,address.PostalCode,…);
_commandExecuter.Execute(clientMovingCommand);
}
  • 获取命令对象(而不是DTO)并执行它的通用服务:
/。。。在远程facade或客户端代码中。。。
var orderActivationCommand=新的orderActivationCommand(orderID);
_commandService.ExecuteCommand(orderActivationCommand);
// ... 在应用层(服务)。。。
public void ExecuteCommand(命令)
{
_commandExeuter.Execute(命令);
}

在CQRS中,命令处理程序基本上就是非CQRS场景中的应用程序服务。

当您遇到设置一致性验证等问题时。例如:您可能需要一个服务来确保传入的重复命令(其值只应保留一次)被拒绝。 在这种情况下,服务基本上在带有主键约束的Sql表中进行插入。它只发生一次,否则将抛出错误,整个过程将失败,并且不会生成任何事件,查询端也不会报告。
只是一个例子。

这是有争议的,因为当我查看实现时,我感觉到服务层的责任在命令处理程序和域级别之间划分。至少我是这样理解Greg的。就在昨天,他在我参加的一个课程上谈到了这个话题。但我肯定也有例外。我指的是图表中提到的服务。您发布了一些我在Greg的实现中已经看到的代码片段,但它们不能帮助我查看逻辑图中的服务是域服务而不是应用程序服务,这是一个与聚合根无关的域逻辑。。与银行转账一样,它是与两个聚合根(实体)相关的域逻辑,因此应该在BankTransferService中实现;即使使用命令和命令处理程序,有时您也无法找到单个聚合根或实体来应用域逻辑,因此您必须依赖域服务检查:如果没有直接链接,它如何更新非规范化数据库?此服务是否发布事件?它不会更新非规范化的数据库。它只是从事件发布服务器或精简数据层调用,以计算或处理某些域逻辑,并将结果作为dto返回以供查询。再检查一下图表好吧,我不这么认为。DDD中的服务旨在包含业务逻辑。Fowler引用的一句话:“服务层从接口客户端层的角度定义了应用程序的边界[Cockburn PloP]及其可用操作集。它封装了应用程序的业务逻辑,控制事务并协调其操作实现中的响应。”。首先-此操作由命令处理程序和域在此完成,第二个是箭头显示此术语服务应用程序不适用。但我可能错了,你把“应用程序服务层”和“域服务”混淆了。这是两件不同的事情。