1

我是CQRS的新成员,想学习模式的工作顺序。我的命令处理程序和命令是这样的:CommandHandler和EventHandler订单

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

当我cerate一个工作一个命令处理程序工作。

public class CreateWorkCommandhandler : ICommandHandler<CreateWork> 
{ 
    public void Handle(CreateWork command) 
    { 
     Save to database...    
    } 
} 

而我不会在控制器类中调用命令处理程序。我使用CommandExecuter按类型调用命令。

public class CommandExecuter 
{ 

    public static void ExecuteCommand<TCommand>(TCommand command) where TCommand : ICommand 
    { 
     var handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType()); 

     var handlers = serviceLocator.GetAll(handlerType); 

     foreach (var handler in handlers) 
      ((dynamic)handler).Handle((dynamic)command); 
    } 
} 

我想发送电子邮件,发送短信和其他东西下班后创建。但由于分离的体系结构,我无法在Handle(CreateWork command)中执行这些步骤。

我认为这些步骤是事件,这是真的吗?所以我需要eventevent handler类型。

public interface IEventHandler<in TEvent> where TEvent : IEvent 
{ 
    void Handle(TEvent event); 
} 

我在哪里填充事件?在CommandExecuterCommandHandler我需要事件的多个事件。例如:

公共类WorkCreated:IEvent {}

发送短信,发送电子邮件。

回答

4
 foreach (var handler in handlers) 
     ((dynamic)handler).Handle((dynamic)command); 

这看起来真的怪异。为什么在一个/上下文中,会有一个以上的命令处理程序?

对于事件消息,该模式可能有意义;一个事件有零个或多个用户是正常的。但命令是发送给特定目标的消息,因此枚举一些处理程序似乎很奇怪。

在你的问题

我要发电子邮件,发送短信和创建工作陆续进行的事情。但由于分离的体系结构,我无法在Handle(CreateWork命令)中执行这些步骤。

我认为这些步骤是事件,这是真的吗?

事件是描述过去发生的事情的消息。这听起来像一场比赛吗?在我看来,你正在描述一个命令 - 你想要一些系统为你发送一封电子邮件。这听起来不像是已经发生的事情?

EmailCommandSucceeded,SMSCommandFailed等更精细的细节 - 那些是事件;过去发生的事情。

中,一条命令是一个改变域状态的提议(前提是更改是由域模型强制执行的业务不变量允许的)。模型的反应通常分为两部分:数据在提交事务时保存(Repository.save()),以及与世界其他地方共享的消息。这些消息可以是域事件,也可以是其他事务/上下文中运行的命令。

因此,对于您的问题的常见答案是,命令处理程序会将命令交给域模型,并取回要排定的命令列表(在事务上下文之外)。

如果命令处理程序不能直接执行此操作,另一种方法可能是发布EmailCommandScheduledEvent,然后让事件处理程序执行相同的工作。

+0

我同意这个foreach不适合处理程序。最好是执行handlers.single()以确保该命令只有一个处理程序。 – user707727