Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

About domain event locator and event listener #3

Open
HallofFamer opened this issue Oct 14, 2015 · 1 comment
Open

About domain event locator and event listener #3

HallofFamer opened this issue Oct 14, 2015 · 1 comment

Comments

@HallofFamer
Copy link

From your code I see that after an event is raised, it must be handled by a particular event listener. And this event listener must be registered in domain event locator, or you wont be able to execute the event. By doing this, you have to manually register event listener at some point of your code, and this is cumbersome. As the application grows and multiple events need to be triggered, it becomes complex to add event listeners manually.

I was wondering, why do you need this behavior? Why cannot you just implement the handler method inside the event object itself, so users do not have to register event listeners manually? Or maybe, you can make it possible to enable easy mapping between each event and its handler(if you want event to be ignorant of how it will be handlered), so the event locator will automatically create an event listener object for each event(ie. map event PurchaseOrderCreated to event listener PurchaseOrderCreatedHandler).

This way, when you iterate through events and publish them through event bus, the event bus will use event locator to automatically map an event to its listener. You wont need to register event listener/handler manually anymore, the code becomes more concise.

Of course, registration of custom event listeners/handlers introduce more flexibility, so it can always be left of as an option. I just personally think that registering event listeners manually can be problematic as the application grows, and it's also confusing where should we register event listeners(in MVC controller, application service, repository?).

@juliendufresne
Copy link
Member

First, thank you for your feedback and let me apologise for the late response.

From your code I see that after an event is raised, it must be handled by a particular event listener.

I just want to be clear on that. An event can be handled by one or more event listeners.

We want to apply separation of concern design principle here. An event object should only describe what it is. It has nothing to do with what we may want to do when it occurs.
Typically, from my understanding of Domain Driven Design, an event is part of your domain - it is something that occurred in your system - but event listeners - actions you want to perform when an event is triggered - may not be part of your domain.
If, for instance, I want to store this event in a database. The corresponding listener will not be part of my Domain layer (reserved for business logic) but directly in my Infrastructure layer (containing all the interface with my database).

If I put the handler inside the Event, I'm forced to execute this handler. Think about A/B testing for instance. You may want to activate the listener at runtime depending on some criteria (user's region, time of the day, ...). In order to do this you have two solutions:

  • Inside your listener, check that the corresponding criteria are met. I'm not fond of this solution because it's not the role of the listener to check if it should be activated or not.
  • When registering your listener, you check that the conditions are met.

We also choose to separate event from listeners because listeners may have some dependencies that the Event doesn't. An event is a POPO (plain old PHP object). It doesn't require anything. On the contrary, event listener needs extra stuff to work: a repository to access a database, a logger service, ...

What we could do is implement a kind of service discovery for listeners. It means search in your entire code source for classes that implements EventListenerInterface, get the event from getSupportedEventClassName() method and subscribe them auto-magically. This is basically the way it's done in the php-ddd-bundle.
But by doing so, we don't have the ability to tell wether we want to subscribe those listeners only when some conditions are met.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants