How, if at all, should a Symfony 2 bundle developer use the event dispatcher(s) that ship with a stock Symfony 2 system?
I've been digging around in the source for Symfony's event dispatcher, and some of what I've seen has me a little confused as to how I, a third party bundle creator, should use the event dispatcher that ships with Symfony.
Specifically, I noticed that a stock Symfony system has two event dispatcher services. The event_dispatcher
and the debug.event_dispatcher
. Which service the HttpKernel uses is dependent on environment, and driven by the generated dev or prod container file.
//dev kernel instantiation uses `debug.event_dispatcher` service
new \Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel(
$this->get('debug.event_dispatcher'),
$this,
$this->get('debug.controller_resolver')
);
//prod kernel instantiation uses `event_dispatcher` service
new \Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel(
$this->get('event_dispatcher'),
$this,
new \Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver($this, $this->get('controller_name_converter'), $this->get('monolog.logger.request', ContainerInterface::NULL_ON_INVALID_REFERENCE)));
So far this all makes sense — as it's the debug.event_dispatcher
that implements functionality in the web profile's event's tab, including the ability to see which listeners were called, and which listeners were not called.
However, I noticed most (if not all) third party bundles use a hard coded event_dispatcher
service call. For example, the JMS/JobQueueBundle uses the following
$this->dispatcher = $this->getContainer()->get('event_dispatcher');
Events dispatched like this fire correctly, but the debug.event_dispatcher
doesn't know about them, which means the Symfony web profiler will incorrectly list a called listener as uncalled. Additionally, it's not clear how a bundle author could avoid this, as they don't have the advantage of generating a container file and the HTTP Kernel object doesn't expose an accessor for the protected dispatcher object.
So, is this a bug in Symfony?
Or is the event_dispatcher
service only intended for Kernel events, meaning all those bundle authors are misusing it?
Or (the most likely candidate), is it something else I'm missing or haven't considered?
The EventDispatcher component provides tools that allow your application components to communicate with each other by dispatching events and listening to them.
Event Dispatchers are an Actor communication method where one Actor dispatches an event and other Actors that are listening to that event are notified.
During the execution of a Symfony application, lots of event notifications are triggered. Your application can listen to these notifications and respond to them by executing any piece of code. Symfony triggers several events related to the kernel while processing the HTTP Request.
The Dispatcher component balances traffic among your servers through a unique combination of load balancing and management software.
It looks like the scenario I described above doesn't apply to that latest version of Symfony (2.4.1
). Specifically, in 2.4.1
, the generated app container file
app/cache/dev/appDevDebugProjectContainer.php
contains the following
$this->aliases = array(
//...
'event_dispatcher' => 'debug.event_dispatcher',
//...
);
That is, unlike the Symfony 2.3.6
project I was working on, the event_dispatcher
service has been aliased to the debug.event_dispatcher
service (when Symfony runs in development mode). This means when other bundles ask for an event_dispatcher
service in dev mode, they're really getting a debug.event_dispatcher
service. This lets the the debug.event_dispatcher
know about all the events, and it can correctly report on which ones were dispatched.
While it's not a concrete answer, it does indicate the Symfony team was/is aware of the issue, which leads me to believe it's their intention for Bundle developers to use the event_dispatch
service fro their own events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With