Reputation: 166046
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?
Upvotes: 13
Views: 6181
Reputation: 166046
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.
Upvotes: 7