diff --git a/src/DependencyInjection/Compiler/RegisterHandlers.php b/src/DependencyInjection/Compiler/RegisterHandlers.php index 891822c..40036b1 100644 --- a/src/DependencyInjection/Compiler/RegisterHandlers.php +++ b/src/DependencyInjection/Compiler/RegisterHandlers.php @@ -4,23 +4,27 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; class RegisterHandlers implements CompilerPassInterface { use CollectServices; - private $serviceId; + private $callableServiceId; + private $serviceLocatorId; private $tag; private $keyAttribute; /** - * @param string $serviceId The service id of the MessageHandlerMap + * @param string $callableServiceId The service id of the MessageHandlerMap + * @param string $serviceLocatorId The service id of the ServiceLocator * @param string $tag The tag name of message handler services * @param string $keyAttribute The name of the tag attribute that contains the name of the handler */ - public function __construct($serviceId, $tag, $keyAttribute) + public function __construct($callableServiceId, $serviceLocatorId, $tag, $keyAttribute) { - $this->serviceId = $serviceId; + $this->callableServiceId = $callableServiceId; + $this->serviceLocatorId = $serviceLocatorId; $this->tag = $tag; $this->keyAttribute = $keyAttribute; } @@ -33,19 +37,25 @@ public function __construct($serviceId, $tag, $keyAttribute) */ public function process(ContainerBuilder $container) { - if (!$container->has($this->serviceId)) { + if (!$container->has($this->callableServiceId)) { return; } - $definition = $container->findDefinition($this->serviceId); + if (!$container->has($this->serviceLocatorId)) { + return; + } + + $callableDefinition = $container->findDefinition($this->callableServiceId); + $serviceLocatorDefinition = $container->findDefinition($this->serviceLocatorId); $handlers = array(); + $services = array(); $this->collectServiceIds( $container, $this->tag, $this->keyAttribute, - function ($key, $serviceId, array $tagAttributes) use (&$handlers) { + function ($key, $serviceId, array $tagAttributes) use (&$handlers, &$services) { if (isset($tagAttributes['method'])) { // Symfony 3.3 supports services by classname. This interferes with `is_callable` // in `ServiceLocatorAwareCallableResolver` @@ -58,9 +68,11 @@ function ($key, $serviceId, array $tagAttributes) use (&$handlers) { } $handlers[ltrim($key, '\\')] = $callable; + $services[$serviceId] = new Reference($serviceId); } ); - $definition->replaceArgument(0, $handlers); + $callableDefinition->replaceArgument(0, $handlers); + $serviceLocatorDefinition->replaceArgument(0, $services); } } diff --git a/src/DependencyInjection/Compiler/RegisterSubscribers.php b/src/DependencyInjection/Compiler/RegisterSubscribers.php index f0816ad..a69f175 100644 --- a/src/DependencyInjection/Compiler/RegisterSubscribers.php +++ b/src/DependencyInjection/Compiler/RegisterSubscribers.php @@ -4,23 +4,27 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; class RegisterSubscribers implements CompilerPassInterface { use CollectServices; - private $serviceId; + private $callableServiceId; + private $serviceLocatorId; private $tag; private $keyAttribute; /** - * @param string $serviceId The service id of the MessageSubscriberCollection - * @param string $tag The tag name of message subscriber services - * @param string $keyAttribute The name of the tag attribute that contains the name of the subscriber + * @param string $callableServiceId The service id of the MessageSubscriberCollection + * @param string $serviceLocatorId The service id of the ServiceLocator + * @param string $tag The tag name of message subscriber services + * @param string $keyAttribute The name of the tag attribute that contains the name of the subscriber */ - public function __construct($serviceId, $tag, $keyAttribute) + public function __construct($callableServiceId, $serviceLocatorId, $tag, $keyAttribute) { - $this->serviceId = $serviceId; + $this->callableServiceId = $callableServiceId; + $this->serviceLocatorId = $serviceLocatorId; $this->tag = $tag; $this->keyAttribute = $keyAttribute; } @@ -33,19 +37,25 @@ public function __construct($serviceId, $tag, $keyAttribute) */ public function process(ContainerBuilder $container) { - if (!$container->has($this->serviceId)) { + if (!$container->has($this->callableServiceId)) { return; } - $definition = $container->findDefinition($this->serviceId); + if (!$container->has($this->serviceLocatorId)) { + return; + } + + $callableDefinition = $container->findDefinition($this->callableServiceId); + $serviceLocatorDefinition = $container->findDefinition($this->serviceLocatorId); $handlers = array(); + $services = array(); $this->collectServiceIds( $container, $this->tag, $this->keyAttribute, - function ($key, $serviceId, array $tagAttributes) use (&$handlers) { + function ($key, $serviceId, array $tagAttributes) use (&$handlers, &$services) { if (isset($tagAttributes['method'])) { // Symfony 3.3 supports services by classname. This interferes with `is_callable` // in `ServiceLocatorAwareCallableResolver` @@ -58,9 +68,11 @@ function ($key, $serviceId, array $tagAttributes) use (&$handlers) { } $handlers[ltrim($key, '\\')][] = $callable; + $services[$serviceId] = new Reference($serviceId); } ); - $definition->replaceArgument(0, $handlers); + $callableDefinition->replaceArgument(0, $handlers); + $serviceLocatorDefinition->replaceArgument(0, $services); } } diff --git a/src/Resources/config/command_bus.yml b/src/Resources/config/command_bus.yml index 8124343..e8187ae 100644 --- a/src/Resources/config/command_bus.yml +++ b/src/Resources/config/command_bus.yml @@ -32,7 +32,14 @@ services: class: SimpleBus\Message\CallableResolver\ServiceLocatorAwareCallableResolver public: false arguments: - - ['@service_container', 'get'] + - ['@simple_bus.command_bus.command_handler_service_locator', 'get'] + + simple_bus.command_bus.command_handler_service_locator: + class: Symfony\Component\DependencyInjection\ServiceLocator + tags: ['container.service_locator'] + arguments: + # collection of command handler service ids, will be provided by the RegisterHandlers compiler pass + - [] simple_bus.command_bus.command_handler_map: class: SimpleBus\Message\CallableResolver\CallableMap diff --git a/src/Resources/config/event_bus.yml b/src/Resources/config/event_bus.yml index b1ad041..cab8b29 100644 --- a/src/Resources/config/event_bus.yml +++ b/src/Resources/config/event_bus.yml @@ -57,7 +57,14 @@ services: class: SimpleBus\Message\CallableResolver\ServiceLocatorAwareCallableResolver public: false arguments: - - ['@service_container', 'get'] + - ['@simple_bus.event_bus.event_subscribers_service_locator', 'get'] + + simple_bus.event_bus.event_subscribers_service_locator: + class: Symfony\Component\DependencyInjection\ServiceLocator + tags: ['container.service_locator'] + arguments: + # collection of command handler service ids, will be provided by the RegisterHandlers compiler pass + - [] simple_bus.event_bus.event_subscribers_collection: class: SimpleBus\Message\CallableResolver\CallableCollection diff --git a/src/SimpleBusCommandBusBundle.php b/src/SimpleBusCommandBusBundle.php index 3232389..0c1f5d2 100644 --- a/src/SimpleBusCommandBusBundle.php +++ b/src/SimpleBusCommandBusBundle.php @@ -37,6 +37,7 @@ public function build(ContainerBuilder $container) $container->addCompilerPass( new RegisterHandlers( 'simple_bus.command_bus.command_handler_map', + 'simple_bus.command_bus.command_handler_service_locator', 'command_handler', 'handles' ) diff --git a/src/SimpleBusEventBusBundle.php b/src/SimpleBusEventBusBundle.php index d8b7b84..baa60ac 100644 --- a/src/SimpleBusEventBusBundle.php +++ b/src/SimpleBusEventBusBundle.php @@ -51,6 +51,7 @@ public function build(ContainerBuilder $container) $container->addCompilerPass( new RegisterSubscribers( 'simple_bus.event_bus.event_subscribers_collection', + 'simple_bus.event_bus.event_subscribers_service_locator', 'event_subscriber', 'subscribes_to' ) diff --git a/tests/Functional/SmokeTest.php b/tests/Functional/SmokeTest.php index 005f8de..72f2dfc 100644 --- a/tests/Functional/SmokeTest.php +++ b/tests/Functional/SmokeTest.php @@ -9,6 +9,8 @@ use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEvent1; use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEvent2; use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEvent3; +use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEventSubscriberUsingInvoke; +use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEventSubscriberUsingPublicMethod; use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\TestCommand; use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\TestKernel; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -68,14 +70,13 @@ public function it_can_auto_register_event_subscribers_using_invoke() self::bootKernel(['environment' => 'config2']); $container = self::$kernel->getContainer(); - $subscriber = $container->get('auto_event_subscriber_using_invoke'); $event = new AutoEvent1(); - $this->assertNull($subscriber->handled); + $this->assertFalse($event->isHandledBy(AutoEventSubscriberUsingInvoke::class)); $container->get('event_bus')->handle($event); - $this->assertSame($event, $subscriber->handled); + $this->assertTrue($event->isHandledBy(AutoEventSubscriberUsingInvoke::class)); } /** @@ -86,16 +87,17 @@ public function it_can_auto_register_event_subscribers_using_public_method() self::bootKernel(['environment' => 'config2']); $container = self::$kernel->getContainer(); - $subscriber = $container->get('auto_event_subscriber_using_public_method'); $event2 = new AutoEvent2(); $event3 = new AutoEvent3(); - $this->assertEmpty($subscriber->handled); + $this->assertFalse($event2->isHandledBy(AutoEventSubscriberUsingPublicMethod::class)); + $this->assertFalse($event3->isHandledBy(AutoEventSubscriberUsingPublicMethod::class)); $container->get('event_bus')->handle($event2); $container->get('event_bus')->handle($event3); - $this->assertSame([$event2, $event3], $subscriber->handled); + $this->assertTrue($event2->isHandledBy(AutoEventSubscriberUsingPublicMethod::class)); + $this->assertTrue($event3->isHandledBy(AutoEventSubscriberUsingPublicMethod::class)); } /** @@ -106,14 +108,13 @@ public function it_can_auto_register_command_handlers_using_invoke() self::bootKernel(['environment' => 'config2']); $container = self::$kernel->getContainer(); - $handler = $container->get('auto_command_handler_using_invoke'); $command = new AutoCommand1(); - $this->assertNull($handler->handled); + $this->assertFalse($command->isHandled()); $container->get('command_bus')->handle($command); - $this->assertSame($command, $handler->handled); + $this->assertTrue($command->isHandled()); } /** @@ -124,14 +125,13 @@ public function it_can_auto_register_command_handlers_using_public_method() self::bootKernel(['environment' => 'config2']); $container = self::$kernel->getContainer(); - $handler = $container->get('auto_command_handler_using_public_method'); $command = new AutoCommand2(); - $this->assertNull($handler->handled); + $this->assertFalse($command->isHandled()); $container->get('command_bus')->handle($command); - $this->assertSame($command, $handler->handled); + $this->assertTrue($command->isHandled()); } /** diff --git a/tests/Functional/SmokeTest/Auto/AutoCommand1.php b/tests/Functional/SmokeTest/Auto/AutoCommand1.php index 66431f8..8a97cfd 100644 --- a/tests/Functional/SmokeTest/Auto/AutoCommand1.php +++ b/tests/Functional/SmokeTest/Auto/AutoCommand1.php @@ -4,4 +4,15 @@ final class AutoCommand1 { + private $handled = false; + + public function isHandled() : bool + { + return $this->handled; + } + + public function setHandled(bool $handled) : void + { + $this->handled = $handled; + } } diff --git a/tests/Functional/SmokeTest/Auto/AutoCommand2.php b/tests/Functional/SmokeTest/Auto/AutoCommand2.php index 4983203..5131ad1 100644 --- a/tests/Functional/SmokeTest/Auto/AutoCommand2.php +++ b/tests/Functional/SmokeTest/Auto/AutoCommand2.php @@ -4,4 +4,15 @@ final class AutoCommand2 { + private $handled = false; + + public function isHandled() : bool + { + return $this->handled; + } + + public function setHandled(bool $handled) : void + { + $this->handled = $handled; + } } diff --git a/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingInvoke.php b/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingInvoke.php index cbe3d5e..9120391 100644 --- a/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingInvoke.php +++ b/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingInvoke.php @@ -4,10 +4,8 @@ final class AutoCommandHandlerUsingInvoke { - public $handled; - public function __invoke(AutoCommand1 $command) { - $this->handled = $command; + $command->setHandled(true); } } diff --git a/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingPublicMethod.php b/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingPublicMethod.php index 5ef73cd..4dc103b 100644 --- a/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingPublicMethod.php +++ b/tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingPublicMethod.php @@ -4,10 +4,8 @@ final class AutoCommandHandlerUsingPublicMethod { - public $handled; - public function someHandleMethod(AutoCommand2 $command) { - $this->handled = $command; + $command->setHandled(true); } } diff --git a/tests/Functional/SmokeTest/Auto/AutoEvent1.php b/tests/Functional/SmokeTest/Auto/AutoEvent1.php index 097d2f1..b308b02 100644 --- a/tests/Functional/SmokeTest/Auto/AutoEvent1.php +++ b/tests/Functional/SmokeTest/Auto/AutoEvent1.php @@ -4,4 +4,15 @@ final class AutoEvent1 { + private $handled = []; + + public function isHandledBy($subscriber) : bool + { + return in_array($subscriber, $this->handled); + } + + public function setHandledBy($subscriber) : void + { + $this->handled[] = get_class($subscriber); + } } diff --git a/tests/Functional/SmokeTest/Auto/AutoEvent2.php b/tests/Functional/SmokeTest/Auto/AutoEvent2.php index 3d2cdf8..aee5920 100644 --- a/tests/Functional/SmokeTest/Auto/AutoEvent2.php +++ b/tests/Functional/SmokeTest/Auto/AutoEvent2.php @@ -4,4 +4,15 @@ final class AutoEvent2 { + private $handled = []; + + public function isHandledBy($subscriber) : bool + { + return in_array($subscriber, $this->handled); + } + + public function setHandledBy($subscriber) : void + { + $this->handled[] = get_class($subscriber); + } } diff --git a/tests/Functional/SmokeTest/Auto/AutoEvent3.php b/tests/Functional/SmokeTest/Auto/AutoEvent3.php index af1bd05..5a7b3b0 100644 --- a/tests/Functional/SmokeTest/Auto/AutoEvent3.php +++ b/tests/Functional/SmokeTest/Auto/AutoEvent3.php @@ -4,4 +4,15 @@ final class AutoEvent3 { + private $handled = []; + + public function isHandledBy($subscriber) : bool + { + return in_array($subscriber, $this->handled); + } + + public function setHandledBy($subscriber) : void + { + $this->handled[] = get_class($subscriber); + } } diff --git a/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingInvoke.php b/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingInvoke.php index 872abd5..13721a1 100644 --- a/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingInvoke.php +++ b/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingInvoke.php @@ -4,11 +4,9 @@ final class AutoEventSubscriberUsingInvoke { - public $handled; - public function __invoke(AutoEvent1 $event) { - $this->handled = $event; + $event->setHandledBy($this); } public function randomPublicMethod($value) diff --git a/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingPublicMethod.php b/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingPublicMethod.php index bcaadf6..b3dd606 100644 --- a/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingPublicMethod.php +++ b/tests/Functional/SmokeTest/Auto/AutoEventSubscriberUsingPublicMethod.php @@ -4,8 +4,6 @@ final class AutoEventSubscriberUsingPublicMethod { - public $handled = []; - public function __construct() { @@ -18,11 +16,11 @@ public function __destruct() public function someEventHandler(AutoEvent2 $event) { - $this->handled[] = $event; + $event->setHandledBy($this); } public function someOtherEventHandler(AutoEvent3 $event) { - $this->handled[] = $event; + $event->setHandledBy($this); } } diff --git a/tests/Functional/SmokeTest/config2.yml b/tests/Functional/SmokeTest/config2.yml index 6978c38..b700488 100644 --- a/tests/Functional/SmokeTest/config2.yml +++ b/tests/Functional/SmokeTest/config2.yml @@ -6,22 +6,22 @@ services: class: SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoCommandHandlerUsingInvoke tags: - { name: command_handler } - public: true + public: false auto_command_handler_using_public_method: class: SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoCommandHandlerUsingPublicMethod tags: - { name: command_handler, register_public_methods: true } - public: true + public: false auto_event_subscriber_using_invoke: class: SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEventSubscriberUsingInvoke tags: - { name: event_subscriber } - public: true + public: false auto_event_subscriber_using_public_method: class: SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEventSubscriberUsingPublicMethod tags: - { name: event_subscriber, register_public_methods: true } - public: true + public: false diff --git a/tests/Functional/SmokeTest/config3.yml b/tests/Functional/SmokeTest/config3.yml index 2312483..ca0ba23 100644 --- a/tests/Functional/SmokeTest/config3.yml +++ b/tests/Functional/SmokeTest/config3.yml @@ -10,7 +10,7 @@ services: - 2 tags: - { name: command_handler, handles: SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Nested\NestedCommand } - public: true + public: false nesting_records_bag: class: SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Nested\RecordsBag