我有一个DDD项目,我不知道直接在订阅服务器中使用Handler还是Service是否更好。
让我澄清一下;对此
我的问题是:如果引发了域事件,则订户应该运行服务还是其他命令处理程序?
让我举个例子:
class CommandOne{
public function __construct(string $stuff){
$this->stuff = $stuff;
}
public function getStuff(){
return $this->stuff;
}
}
// Handler, called from a ControllerAction
class HandlerCommandOne{
public function __construct(StuffRepository $stuffRepository,
SomeService $service){
$this->service = $service;
$this->stuffRepository = $stuffRepository;
}
public function handle(CommandOne $command){
$stuff = $command->getStuff();
$stuffModel = $this->stuffRepository->find($stuff);
//Some Business Logic
$this->service->doBusinessActivity();
$this->anotherService->doAnotherBusinessActivity();
// If I want that subscriber will use Service , I inject a model in event constructor
$this->dispatcher->dispatch(StuffEvent::NAME,new StuffEvent($stuffModel));
// If I want that subscriber will use a CommandHandler , I inject primitives in event constructor
$this->dispatcher->dispatch(StuffEvent::NAME,new StuffEvent($stuffModel->getId(),$stuffModel->getName()));
}
}
class SomeSubscriberWithHandler{
public function __construct(CommandHandler $handler) {
$this->handler = $handler;
}
public function OnStuffEvent($event){
$command = new SomeOtherCommand($event->getId(), $event->getName());
$this->handler->handle($command); // Handle will handle logic calling other services ...
}
}
class SomeSubscriberWithService{
public function __construct(Service $service) {
$this->service = $service;
}
public function OnStuffEvent($event){
$model = $event->getModel();
$this->service->doLogic($model);
}
}
我看到优点和缺点;我知道,在DDD中,最好使用PRIMITIVES数据创建事件,因为事件可以在有限的上下文之外捕获,而您的模型没有意义。
但是,如果我使用原始类型,那么每次我需要从实体中获取信息时,都必须调用存储库。
例如,订户必须通知新模型已创建,并发送电子邮件;您将在订阅服务器中创建处理程序,还是直接在服务中创建?
预先感谢
答案 0 :(得分:0)
鉴于我们通过消息队列(MQ)实现了边界上下文(BC)之间的通信,上游BC将通过将域事件转换为将发送到MQ的消息来发布域事件。
另一方面,下游BC中的订户将是一个侦听器,它将将从MQ接收的消息转换为命令,然后运行命令处理程序。
侦听器具有基础结构,因为它处理技术(MQ)。它在应用程序外部,接收消息并调用应用程序服务(或命令处理程序)。
这是在红皮书(实施域驱动设计)的示例中完成的。您可以在https://github.com/VaughnVernon/IDDD_Samples
上查看他们