以DDD的方式注入EventDispatcher到实体中



以DDD方式将EventDispatcher注入实体是正确的吗?

假设我有一个名为Card的DomainModel。这张卡是一种通用语言,可以激活和停用。但是激活和停用涉及到对第三方API的调用,它在现实世界中激活。

因此,为了保持我们的领域模型清晰,我的方法是我的Card实体有一个激活方法,看起来像:

public function activate()
{
    $this->active = true;
    $this->dispatcher->dispatch(CardEvents::CARD_ACTIVATION, new CardActivation($this));
}

则服务正在监听调度程序,以使用外部API激活或不激活。

是否正确注入到一个实体这个EventDispatcher?

如果对api的调用失败,方法是什么?

有没有感觉侦听服务最终改变了Card本身的活动属性?

谢谢。

如果激活方法中的这个EventDispatcher只是对来自域的接口的引用,那么是的,它是可以的。然后,你可以将这个接口从你的领域公开到另一层,并创建一个实现该接口的类(例如在应用层),这个类可以使用第三方库或其他任何东西来实现。这样,您的域就不知道IEventDispatcher接口是如何实现的,从而使其免受更改。

记住,改变EventDispatcher的实现方式(如果它使用第三方插件,或者如果你自己实现)不应该影响你的域/业务逻辑。也许使用它的应用程序会受到影响。你可能有很多应用程序(web、移动、桌面)都有可能停用一张卡,每个应用程序都有不同的EventDispatcher版本/实现(或相同),这不会影响你的域。如果是,那么你应该检查你的设计。

此外,我将保持EventDispatcher在你的卡模型只有当你必须调用它不管什么应用程序(web,桌面,移动,webservice)请求activate()方法,这意味着调用的一些EventDispatcherdispatch()方法是你的业务逻辑的一部分(注意强调一些字,因为域不知道任何关于它是如何实现的,它)。仅仅因为你的域想给应用程序一个执行调度的机会,不管它是否工作,不管它是否做了什么(域不关心它,它只是调用它)。