Dependency injection CQRS-在命令中执行命令

Dependency injection CQRS-在命令中执行命令,dependency-injection,cqrs,Dependency Injection,Cqrs,我最近看到一些代码场景,其中CommandHandler被注入ICommandExecutor以调用其他命令。所以命令中的命令。对于一些被注射了IQuery的QueryHandler来说也是如此 public class UpdateCarDetailsCommandHandler : CommandHandler<UUpdateCarDetailsCommand> { private ICommandExecutor _command; public UpdateCa

我最近看到一些代码场景,其中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())   
    }
}
公共类UpdateCarDetailsCommandHandler:CommandHandler
{
专用ICommandExecutor_命令;
public UpdateCarDetailsCommandHandler(ICommandExecutor命令)
{
_命令=命令;
}     
public override void Execute(UpdateCarDetailsCommand命令)
{
//对存储库做些什么
_command.Execute(新的carcolor())
}
}

这对我来说似乎不正确,因为在这个场景中,ICommandExecutor将是合成根。只是想知道人们对此有何想法?

我说,在其他命令和查询中谨慎使用命令和查询是正确的小心做得太多的抽象。

中的S代表。这显然意味着命令应该与其他命令分开,查询应该与其他查询分开。但是查询可以被命令使用吗?和往常一样,这要视情况而定

Udi Dahan 2009年的研究表明:

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

Dino Esposito使用单独的项目:

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

我个人的观点是,您应该将这些标准命令和查询处理程序看作是整体抽象。整体抽象是与整个事务相关的抽象;在单个事务的范围内,它不能是比自身更大的依赖项

取而代之的是类似的抽象对,它们是可注入的策略,可以用交叉关注点来修饰

例如

公共接口IDataCommandHandler,其中TCommand:IDataCommand
{
无效句柄(TCommand命令);
}
公共接口IDataQueryHandler,其中TQuery:IDataQuery
{
TResult句柄(TQuery查询);
}

公共接口ICommandStrategyHandler,其中TCommand:ICommand
{
无效句柄(TCommand命令);
} 
公共接口IQueryStrategyHandler,其中TQuery:IQuery
{
TResult句柄(TQuery查询);
}

我听说有人认为使用ing命令的命令是不可以的,您应该创建一个服务来完成这项工作,并在两个命令中调用该服务。但命令中的查询(或其他查询)对我来说似乎没问题,因为没有副作用。请阅读。
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);
}