Greg Young的CQRS实施中的服务目的

时间:2011-09-19 19:33:22

标签: c# domain-driven-design cqrs

我决定以Greg Young's implementation

为例了解具体的CQRS实施

我不明白这里服务的含义是什么,因为它似乎完全不同于我们常用的三层模式。

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

然后创建事件并将其存储在事件存储库中并发布以同步去除denormolized部分。

我找不到这个链中的服务。

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

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

任何人都可以解释一下这里应该做什么服务吗?

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:1)

'服务'可以代表不同的东西,具体取决于您所讨论的上下文。阅读文章我相信他在Domain Services form the building blocks of DDD {/ 3}}的背景下使用了“服务”一词。

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

答案 2 :(得分:0)

你的意思是服务远程外观(Web服务),它将调用应用程序层,因为域服务是另一回事。

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

对于Read Part,在您的应用程序层中,您需要使用FindOrders(x, y, z)GetMostOrderedItems(),...等方法设计查询服务。

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

  • 采用DTO并基于它执行域逻辑的服务[最少CQRS]:
public void ActivateOrder(int orderID)
{
    var order = _orderRepository.FindOrder(orderID);
    order.Activate();
}

public void UpdateClientAddress(ClientAddressDTO address)
{
    var client = _clientRepository.FindClient(address.ClientID);
    client.Address = // .. map ClientAddressDTO to Address
}
  • 使用DTO并将其转换为要在域模型上执行的命令的服务:
public void ActivateOrder(int orderID)
{
    var orderActivationCommand = new OrderActivationCommand(orderID);
    _commandExecuter.Execute(orderActivationCommand);
}

public void UpdateClientAddress(ClientAddressDTO address)
{
    var clientMovingCommand = new clientMovingCommand(address.ClientID, address.PostalCode, ...);
    _commandExecuter.Execute(clientMovingCommand);
}
  • 接受Command对象(而不是DTO)并执行它的通用服务:
// ... in remote facade or client code ...

var orderActivationCommand = new OrderActivationCommand(orderID);
_commandService.ExecuteCommand(orderActivationCommand);

// ... in application layer (service) ...

public void ExecuteCommand(Command command)
{
    _commandExeuter.Execute(command);
}

答案 3 :(得分:0)

遇到设置一致性验证等问题时。例如:Set Validation Post in SO您可能需要一个服务,以确保拒绝仅应持久一次的值的传入重复命令。 在这种情况下,服务基本上在具有主键约束的Sql表中进行插入。它只发生一次,否则,抛出错误,整个过程失败,没有生成事件,查询端没有报告。 只是一个案例。