CQRS-在命令中执行命令 [英] CQRS - Executing Commands within Commands

查看:85
本文介绍了CQRS-在命令中执行命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近看到了一些代码方案,其中向CommandHandlers注入了ICommandExecutor以调用其他命令。因此命令内的命令。对于某些使用IQuery注入的QueryHandler,也是如此。

I recently saw some code scenarios where CommandHandlers were being injected with ICommandExecutor to call other commands. So commands within commands. This was also true for some QueryHandlers being injected with IQuery.

public class UpdateCarDetailsCommandHandler : CommandHandler<UUpdateCarDetailsCommand>
{
   private ICommandExecutor _command;

   public UpdateCarDetailsCommandHandler (ICommandExecutor command)
   {
       _command = command;
   }     

    public override void Execute(UpdateCarDetailsCommand command)
    {
        //do something with repository 
        _command.Execute(new CarColour())   
    }
}

在我看来,这是不正确的,因为ICommandExecutor将是此方案中的合成根。只是想知道人们对此有何想法?

This seems incorrect to me, as the ICommandExecutor would be the composition root in this scenario. Just wondered people thoughts on this?

推荐答案

我说您很警惕在其他命令和查询中使用命令和查询。 提防过多的抽象。

I say you are correct to be wary of using commands and queries within other commands and queries. Beware abstractions that do too much.

CQRS 代表隔离。这显然意味着命令应与其他命令保持独立,查询应与其他查询保持独立。但是命令可以使用查询吗?与往常一样,这取决于。

The S in CQRS stands for Segregation. This clearly implies that Commands should remain separate from other Commands and Queries should remain separate from other Queries. But can queries be used by commands? As always, it depends.

乌迪·达罕(Udi Dahan)的文章从2009年开始建议不要这样做:

Udi Dahan's article from 2009 suggests not:


由于您的查询现在是在与主数据库不同的数据存储之外执行的,并且无需假设正在提供的数据是100%最新的,您可以轻松地添加这些存储的更多实例,而不必担心它们不包含完全相同的数据。

Since your queries are now being performed off of a separate data store than your master database, and there is no assumption that the data that’s being served is 100% up to date, you can easily add more instances of these stores without worrying that they don’t contain the exact same data.

Dino Esposito 建议使用单独的项目:

Dino Esposito recommends using separate projects:


应用CQRS意味着您将使用两个不同的中间层。一层负责更改系统状态的命令。另一个检索数据。您创建了几个类库项目(查询堆栈和命令堆栈),并且都从主Web服务器项目中进行引用。

Applying CQRS means you’ll use two distinct middle tiers. One tier takes care of commands that alter the system state. The other retrieves the data. You create a couple of class library projects—query stack and command stack—and reference both from the main Web server project.

我的个人认为您应该将这些 standard 命令和查询处理程序视为整体抽象。整体抽象是与整个交易有关的抽象。在单个交易的范围内,它不能是大于自身范围内的依赖项

My personal view is that you should think of these standard Command and Query handlers as holistic abstractions. A holistic abstraction is an abstraction that is concerned with the whole transaction; it cannot be a dependency within something larger than itself within the confines of a single transaction.

相反,需要的是类似的成对抽象,它们是可注入的策略,并且可以用跨领域的关注点来装饰。

What is needed instead are similar pairs of abstractions that are injectable strategies and that can be decorated with cross-cutting concerns.

例如

public interface IDataCommandHandler<TCommand> where TCommand : IDataCommand
{
    void Handle(TCommand command);
}

public interface IDataQueryHandler<TQuery, TResult> where TQuery : IDataQuery<TResult>
{
    TResult Handle(TQuery query);
}

public interface ICommandStrategyHandler<TCommand> where TCommand : ICommand
{
    void Handle(TCommand command);
} 

public interface IQueryStrategyHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
    TResult Handle(TQuery query);
}

这篇关于CQRS-在命令中执行命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆