Merge remote branch 'vicb/service-event'

* vicb/service-event:
  [FrameworkBundle] Optimization of the method ContainerAwareEventDispacther::dispatch()
  [FrameworkBundle] Fix an issue with ContainerAwareEventDispatcher when re-entering a scope
This commit is contained in:
Fabien Potencier 2011-04-24 22:06:56 +02:00
commit 59c6609aec
2 changed files with 59 additions and 3 deletions

View File

@ -36,6 +36,12 @@ class ContainerAwareEventDispatcher extends EventDispatcher
*/
private $listenerIds = array();
/**
* The services registered as listeners
* @var array
*/
private $listeners = array();
/**
* Constructor.
*
@ -79,7 +85,16 @@ class ContainerAwareEventDispatcher extends EventDispatcher
{
if (isset($this->listenerIds[$eventName])) {
foreach ($this->listenerIds[$eventName] as $serviceId => $priority) {
$this->addListener($eventName, $this->container->get($serviceId), $priority);
$listener = $this->container->get($serviceId);
if (!isset($this->listeners[$eventName][$serviceId])) {
$this->addListener($eventName, $listener, $priority);
} elseif ($listener !== $this->listeners[$eventName][$serviceId]) {
$this->removeListener($eventName, $this->listeners[$eventName][$serviceId]);
$this->addListener($eventName, $listener, $priority);
}
$this->listeners[$eventName][$serviceId] = $listener;
}
}

View File

@ -60,17 +60,58 @@ class ContainerAwareEventDispatcherTest extends \PHPUnit_Framework_TestCase
$service = $this->getMock('Symfony\Bundle\FrameworkBundle\Tests\Service');
$scope = new Scope('scope');
$container = new Container();
$container->addScope($scope);
$container->enterScope('scope');
$container->set('service.listener', $service, 'scope');
$dispatcher = new ContainerAwareEventDispatcher($container);
$dispatcher->addListenerService('onEvent', 'service.listener');
$container->leaveScope('scope');
$dispatcher->dispatch('onEvent');
$dispatcher->dispatch('onEvent');
}
public function testReEnteringAScope()
{
$event = new Event();
$service1 = $this->getMock('Symfony\Bundle\FrameworkBundle\Tests\Service');
$service1
->expects($this->exactly(2))
->method('onEvent')
->with($event)
;
$scope = new Scope('scope');
$container = new Container();
$container->addScope($scope);
$container->enterScope('scope');
$container->set('service.listener', $service1, 'scope');
$dispatcher = new ContainerAwareEventDispatcher($container);
$dispatcher->addListenerService('onEvent', 'service.listener');
$dispatcher->dispatch('onEvent', $event);
$service2 = $this->getMock('Symfony\Bundle\FrameworkBundle\Tests\Service');
$service2
->expects($this->once())
->method('onEvent')
->with($event)
;
$container->enterScope('scope');
$container->set('service.listener', $service2, 'scope');
$dispatcher->dispatch('onEvent', $event);
$container->leaveScope('scope');
$dispatcher->dispatch('onEvent');
}
}