CQRS - 在命令中执行命令

TBD*_*TBD 4 dependency-injection cqrs

我最近看到了一些代码方案,其中CommandHandler被注入了ICommandExecutor来调用其他命令.所以命令中的命令.对于一些注入IQuery的QueryHandler也是如此.

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())   
    }
}
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎不正确,因为ICommandExecutor将是此场景中的组合根.只是想知道人们对此的看法?

quj*_*jck 9

我说你在其他命令和查询中使用命令和查询时要小心谨慎.注意做太多的抽象.

CQRS中的S 代表隔离.这显然意味着命令应该与其他命令保持分离,并且查询应该与其他查询保持分离.但命令可以使用查询吗?一如既往,这取决于.

Udi Dahan 在2009年的文章中建议不要:

由于您的查询现在是在与主数据库不同的单独数据存储中执行的,并且不会假设所提供的数据是100%最新的,因此您可以轻松添加这些商店的更多实例,而不必担心它们不会不包含完全相同的数据.

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

应用CQRS意味着您将使用两个不同的中间层.一层负责处理改变系统状态的命令.另一个检索数据.您可以从主Web服务器项目创建几个类库项目 - 查询堆栈和命令堆栈 - 并引用它们.

我个人认为,您应该将这些标准的 Command和Query处理程序视为整体抽象.整体抽象是一种与整个交易有关的抽象; 在单个事务的范围内,它不能成为比自身更大的依赖.

相反,需要的是类似的抽象对,这些抽象是可注射策略并且可以用横切关注点进行修饰.

例如

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

public interface IDataQueryHandler<TQuery, TResult> where TQuery : IDataQuery<TResult>
{
    TResult Handle(TQuery query);
}
Run Code Online (Sandbox Code Playgroud)

要么

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

public interface IQueryStrategyHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
    TResult Handle(TQuery query);
}
Run Code Online (Sandbox Code Playgroud)