我是关于CQRS的新手,想学习模式的工作顺序。我的命令处理程序和命令是这样的:
public interface ICommandHandler<in TCommand> where TCommand : ICommand
{
void Handle(TCommand command);
}
当我停止工作时,命令处理程序正在运行。
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)
中执行这些步骤。
我认为这些步骤都是事件,这是真的吗?所以我需要event
和event handler
类型。
public interface IEventHandler<in TEvent> where TEvent : IEvent
{
void Handle(TEvent event);
}
我可以在哪里填充活动?在 CommandExecuter 或 CommandHandler 中,我需要为事件提供多个事件。例如:
public class WorkCreated:IEvent {}
发送短信,发送电子邮件。
答案 0 :(得分:4)
foreach (var handler in handlers)
((dynamic)handler).Handle((dynamic)command);
看起来真的很奇怪。为什么在ddd / cqrs上下文中,命令会有多个处理程序?
对于事件消息,该模式可能有意义;一个事件拥有零个或多个订阅者是正常的。但命令是发送给特定目标的消息,因此枚举许多处理程序似乎很奇怪。
关于你的问题
我希望在创建工作后发送电子邮件并发送短信和其他内容。但由于分离的体系结构,我无法在Handle(CreateWork命令)中执行这些步骤。
我认为这些步骤都是事件,这是真的吗?
事件是描述过去发生的事情的消息。这听起来像是一场比赛吗?在我看来,您正在描述一个命令 - 您希望某个系统为您发送电子邮件。这听起来不像是已经发生过的事情了吗?
EmailCommandSucceeded,SMSCommandFailed等等更精细的细节 - 那些是事件;过去发生的事情。
在ddd中,命令是更改域状态的提议(前提是域模型强制执行的业务不变量允许更改)。模型的响应通常分为两部分;提交事务(Repository.save())时要保留的数据,以及与世界其他地方共享的消息。这些消息可以是域事件,也可以是在其他事务/上下文中运行的命令。
因此,您的问题的通常答案是命令处理程序将命令关闭到域模型,并返回要调度的命令列表(在事务上下文之外)。
如果命令处理程序不能直接执行此操作,则可以选择发布EmailCommandScheduledEvent,然后让事件处理程序执行相同的工作。