Reputation: 434
is it correct in a DDD way to inject an EventDispatcher into an entity?
Imagine that I have a DomainModel called Card. This card in an ubiquitous language can be activated and deactivated. But the activation and deactivation involves a call to a third party API that it activates in the real world.
So to keep our Domain Models clear my approach is my Card entity has a activate method that looks like:
public function activate()
{
$this->active = true;
$this->dispatcher->dispatch(CardEvents::CARD_ACTIVATION, new CardActivation($this));
}
Then a service is listening the dispatcher to activate or not activate using an external API.
Is it correct to inject into an entity this EventDispatcher?
What is the approach if the call to the api fails?
Has any sense that the listening service changes finally the active property of the Card itself?
Thanks.
Upvotes: 2
Views: 513
Reputation: 10695
If this EventDispatcher inside the activate method is just a reference to an interface from the domain, then yes, it's ok. Then you would expose this interface from your domain to another layer and create a class (e.g in the application layer) implementing said interface, and this class could be implemented using a third party library or anything else. That way, your domain don't know how the IEventDispatcher
interface is implemented, keeping it safe from changes.
Keep in mind changing the way this EventDispatcher is implemented (if it uses a third-party plugin, or if you implemented by yourself) shouldn't affect your domain/business logic. Maybe the application consuming it could be affected. You could have many applications (web, mobile, desktop) with the possibility to deactive a Card, each one with a different EventDispatcher version/implementation (or the same), and this can't affect your domain. If it does, then you should review your design.
Moreover, I'd keep the EventDispatcher inside your Card model only if you must call it regardless of what application (web, desktop, mobile, webservice) is requesting the activate()
method, which means calling the dispatch()
method of some EventDispatcher is part of your business logic (note the emphasis on the some word, since the domain doesn't know anything about how it is implemented, it ), just because your domain want to give the application a chance of doing a dispatch, no matter if it works or not, if it does something or not (the domain doesn't care about it, it just calls it).
Upvotes: 1