Skip to content

Commit c06f1f1

Browse files
committed
Use ServiceLocator to allow for private handlers and subscribers
1 parent bf2db5d commit c06f1f1

18 files changed

+137
-50
lines changed

src/DependencyInjection/Compiler/RegisterHandlers.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,27 @@
44

55
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
66
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
use Symfony\Component\DependencyInjection\Reference;
78

89
class RegisterHandlers implements CompilerPassInterface
910
{
1011
use CollectServices;
1112

12-
private $serviceId;
13+
private $callableServiceId;
14+
private $serviceLocatorId;
1315
private $tag;
1416
private $keyAttribute;
1517

1618
/**
17-
* @param string $serviceId The service id of the MessageHandlerMap
19+
* @param string $callableServiceId The service id of the MessageHandlerMap
20+
* @param string $serviceLocatorId The service id of the ServiceLocator
1821
* @param string $tag The tag name of message handler services
1922
* @param string $keyAttribute The name of the tag attribute that contains the name of the handler
2023
*/
21-
public function __construct($serviceId, $tag, $keyAttribute)
24+
public function __construct($callableServiceId, $serviceLocatorId, $tag, $keyAttribute)
2225
{
23-
$this->serviceId = $serviceId;
26+
$this->callableServiceId = $callableServiceId;
27+
$this->serviceLocatorId = $serviceLocatorId;
2428
$this->tag = $tag;
2529
$this->keyAttribute = $keyAttribute;
2630
}
@@ -33,19 +37,25 @@ public function __construct($serviceId, $tag, $keyAttribute)
3337
*/
3438
public function process(ContainerBuilder $container)
3539
{
36-
if (!$container->has($this->serviceId)) {
40+
if (!$container->has($this->callableServiceId)) {
3741
return;
3842
}
3943

40-
$definition = $container->findDefinition($this->serviceId);
44+
if (!$container->has($this->serviceLocatorId)) {
45+
return;
46+
}
47+
48+
$callableDefinition = $container->findDefinition($this->callableServiceId);
49+
$serviceLocatorDefinition = $container->findDefinition($this->serviceLocatorId);
4150

4251
$handlers = array();
52+
$services = array();
4353

4454
$this->collectServiceIds(
4555
$container,
4656
$this->tag,
4757
$this->keyAttribute,
48-
function ($key, $serviceId, array $tagAttributes) use (&$handlers) {
58+
function ($key, $serviceId, array $tagAttributes) use (&$handlers, &$services) {
4959
if (isset($tagAttributes['method'])) {
5060
// Symfony 3.3 supports services by classname. This interferes with `is_callable`
5161
// in `ServiceLocatorAwareCallableResolver`
@@ -58,9 +68,11 @@ function ($key, $serviceId, array $tagAttributes) use (&$handlers) {
5868
}
5969

6070
$handlers[ltrim($key, '\\')] = $callable;
71+
$services[$serviceId] = new Reference($serviceId);
6172
}
6273
);
6374

64-
$definition->replaceArgument(0, $handlers);
75+
$callableDefinition->replaceArgument(0, $handlers);
76+
$serviceLocatorDefinition->replaceArgument(0, $services);
6577
}
6678
}

src/DependencyInjection/Compiler/RegisterSubscribers.php

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,27 @@
44

55
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
66
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
use Symfony\Component\DependencyInjection\Reference;
78

89
class RegisterSubscribers implements CompilerPassInterface
910
{
1011
use CollectServices;
1112

12-
private $serviceId;
13+
private $callableServiceId;
14+
private $serviceLocatorId;
1315
private $tag;
1416
private $keyAttribute;
1517

1618
/**
17-
* @param string $serviceId The service id of the MessageSubscriberCollection
18-
* @param string $tag The tag name of message subscriber services
19-
* @param string $keyAttribute The name of the tag attribute that contains the name of the subscriber
19+
* @param string $callableServiceId The service id of the MessageSubscriberCollection
20+
* @param string $serviceLocatorId The service id of the ServiceLocator
21+
* @param string $tag The tag name of message subscriber services
22+
* @param string $keyAttribute The name of the tag attribute that contains the name of the subscriber
2023
*/
21-
public function __construct($serviceId, $tag, $keyAttribute)
24+
public function __construct($callableServiceId, $serviceLocatorId, $tag, $keyAttribute)
2225
{
23-
$this->serviceId = $serviceId;
26+
$this->callableServiceId = $callableServiceId;
27+
$this->serviceLocatorId = $serviceLocatorId;
2428
$this->tag = $tag;
2529
$this->keyAttribute = $keyAttribute;
2630
}
@@ -33,19 +37,25 @@ public function __construct($serviceId, $tag, $keyAttribute)
3337
*/
3438
public function process(ContainerBuilder $container)
3539
{
36-
if (!$container->has($this->serviceId)) {
40+
if (!$container->has($this->callableServiceId)) {
3741
return;
3842
}
3943

40-
$definition = $container->findDefinition($this->serviceId);
44+
if (!$container->has($this->serviceLocatorId)) {
45+
return;
46+
}
47+
48+
$callableDefinition = $container->findDefinition($this->callableServiceId);
49+
$serviceLocatorDefinition = $container->findDefinition($this->serviceLocatorId);
4150

4251
$handlers = array();
52+
$services = array();
4353

4454
$this->collectServiceIds(
4555
$container,
4656
$this->tag,
4757
$this->keyAttribute,
48-
function ($key, $serviceId, array $tagAttributes) use (&$handlers) {
58+
function ($key, $serviceId, array $tagAttributes) use (&$handlers, &$services) {
4959
if (isset($tagAttributes['method'])) {
5060
// Symfony 3.3 supports services by classname. This interferes with `is_callable`
5161
// in `ServiceLocatorAwareCallableResolver`
@@ -58,9 +68,11 @@ function ($key, $serviceId, array $tagAttributes) use (&$handlers) {
5868
}
5969

6070
$handlers[ltrim($key, '\\')][] = $callable;
71+
$services[$serviceId] = new Reference($serviceId);
6172
}
6273
);
6374

64-
$definition->replaceArgument(0, $handlers);
75+
$callableDefinition->replaceArgument(0, $handlers);
76+
$serviceLocatorDefinition->replaceArgument(0, $services);
6577
}
6678
}

src/Resources/config/command_bus.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@ services:
3232
class: SimpleBus\Message\CallableResolver\ServiceLocatorAwareCallableResolver
3333
public: false
3434
arguments:
35-
- ['@service_container', 'get']
35+
- ['@simple_bus.command_bus.command_handler_service_locator', 'get']
36+
37+
simple_bus.command_bus.command_handler_service_locator:
38+
class: Symfony\Component\DependencyInjection\ServiceLocator
39+
tags: ['container.service_locator']
40+
arguments:
41+
# collection of command handler service ids, will be provided by the RegisterHandlers compiler pass
42+
- []
3643

3744
simple_bus.command_bus.command_handler_map:
3845
class: SimpleBus\Message\CallableResolver\CallableMap

src/Resources/config/event_bus.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,14 @@ services:
5757
class: SimpleBus\Message\CallableResolver\ServiceLocatorAwareCallableResolver
5858
public: false
5959
arguments:
60-
- ['@service_container', 'get']
60+
- ['@simple_bus.event_bus.event_subscribers_service_locator', 'get']
61+
62+
simple_bus.event_bus.event_subscribers_service_locator:
63+
class: Symfony\Component\DependencyInjection\ServiceLocator
64+
tags: ['container.service_locator']
65+
arguments:
66+
# collection of command handler service ids, will be provided by the RegisterHandlers compiler pass
67+
- []
6168

6269
simple_bus.event_bus.event_subscribers_collection:
6370
class: SimpleBus\Message\CallableResolver\CallableCollection

src/SimpleBusCommandBusBundle.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public function build(ContainerBuilder $container)
3737
$container->addCompilerPass(
3838
new RegisterHandlers(
3939
'simple_bus.command_bus.command_handler_map',
40+
'simple_bus.command_bus.command_handler_service_locator',
4041
'command_handler',
4142
'handles'
4243
)

src/SimpleBusEventBusBundle.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public function build(ContainerBuilder $container)
5151
$container->addCompilerPass(
5252
new RegisterSubscribers(
5353
'simple_bus.event_bus.event_subscribers_collection',
54+
'simple_bus.event_bus.event_subscribers_service_locator',
5455
'event_subscriber',
5556
'subscribes_to'
5657
)

tests/Functional/SmokeTest.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEvent1;
1010
use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEvent2;
1111
use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEvent3;
12+
use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEventSubscriberUsingInvoke;
13+
use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\Auto\AutoEventSubscriberUsingPublicMethod;
1214
use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\TestCommand;
1315
use SimpleBus\SymfonyBridge\Tests\Functional\SmokeTest\TestKernel;
1416
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
@@ -68,14 +70,13 @@ public function it_can_auto_register_event_subscribers_using_invoke()
6870
self::bootKernel(['environment' => 'config2']);
6971
$container = self::$kernel->getContainer();
7072

71-
$subscriber = $container->get('auto_event_subscriber_using_invoke');
7273
$event = new AutoEvent1();
7374

74-
$this->assertNull($subscriber->handled);
75+
$this->assertFalse($event->isHandledBy(AutoEventSubscriberUsingInvoke::class));
7576

7677
$container->get('event_bus')->handle($event);
7778

78-
$this->assertSame($event, $subscriber->handled);
79+
$this->assertTrue($event->isHandledBy(AutoEventSubscriberUsingInvoke::class));
7980
}
8081

8182
/**
@@ -86,16 +87,17 @@ public function it_can_auto_register_event_subscribers_using_public_method()
8687
self::bootKernel(['environment' => 'config2']);
8788
$container = self::$kernel->getContainer();
8889

89-
$subscriber = $container->get('auto_event_subscriber_using_public_method');
9090
$event2 = new AutoEvent2();
9191
$event3 = new AutoEvent3();
9292

93-
$this->assertEmpty($subscriber->handled);
93+
$this->assertFalse($event2->isHandledBy(AutoEventSubscriberUsingPublicMethod::class));
94+
$this->assertFalse($event3->isHandledBy(AutoEventSubscriberUsingPublicMethod::class));
9495

9596
$container->get('event_bus')->handle($event2);
9697
$container->get('event_bus')->handle($event3);
9798

98-
$this->assertSame([$event2, $event3], $subscriber->handled);
99+
$this->assertTrue($event2->isHandledBy(AutoEventSubscriberUsingPublicMethod::class));
100+
$this->assertTrue($event3->isHandledBy(AutoEventSubscriberUsingPublicMethod::class));
99101
}
100102

101103
/**
@@ -106,14 +108,13 @@ public function it_can_auto_register_command_handlers_using_invoke()
106108
self::bootKernel(['environment' => 'config2']);
107109
$container = self::$kernel->getContainer();
108110

109-
$handler = $container->get('auto_command_handler_using_invoke');
110111
$command = new AutoCommand1();
111112

112-
$this->assertNull($handler->handled);
113+
$this->assertFalse($command->isHandled());
113114

114115
$container->get('command_bus')->handle($command);
115116

116-
$this->assertSame($command, $handler->handled);
117+
$this->assertTrue($command->isHandled());
117118
}
118119

119120
/**
@@ -124,14 +125,13 @@ public function it_can_auto_register_command_handlers_using_public_method()
124125
self::bootKernel(['environment' => 'config2']);
125126
$container = self::$kernel->getContainer();
126127

127-
$handler = $container->get('auto_command_handler_using_public_method');
128128
$command = new AutoCommand2();
129129

130-
$this->assertNull($handler->handled);
130+
$this->assertFalse($command->isHandled());
131131

132132
$container->get('command_bus')->handle($command);
133133

134-
$this->assertSame($command, $handler->handled);
134+
$this->assertTrue($command->isHandled());
135135
}
136136

137137
/**

tests/Functional/SmokeTest/Auto/AutoCommand1.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,15 @@
44

55
final class AutoCommand1
66
{
7+
private $handled = false;
8+
9+
public function isHandled() : bool
10+
{
11+
return $this->handled;
12+
}
13+
14+
public function setHandled(bool $handled) : void
15+
{
16+
$this->handled = $handled;
17+
}
718
}

tests/Functional/SmokeTest/Auto/AutoCommand2.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,15 @@
44

55
final class AutoCommand2
66
{
7+
private $handled = false;
8+
9+
public function isHandled() : bool
10+
{
11+
return $this->handled;
12+
}
13+
14+
public function setHandled(bool $handled) : void
15+
{
16+
$this->handled = $handled;
17+
}
718
}

tests/Functional/SmokeTest/Auto/AutoCommandHandlerUsingInvoke.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
final class AutoCommandHandlerUsingInvoke
66
{
7-
public $handled;
8-
97
public function __invoke(AutoCommand1 $command)
108
{
11-
$this->handled = $command;
9+
$command->setHandled(true);
1210
}
1311
}

0 commit comments

Comments
 (0)