bug #37569 [Messenger] Allow same middleware to be used multiple times with different arguments (HypeMC)

This PR was merged into the 4.4 branch.

Discussion
----------

[Messenger] Allow same middleware to be used multiple times with different arguments

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #37568
| License       | MIT
| Doc PR        | -

Middleware service names now take into account arguments as well to allow the same middleware to be used multiple times with different arguments:
```yaml
framework:
    messenger:
        buses:
            messenger.bus.default:
                middleware:
                    - doctrine_ping_connection: ['main']
                    - doctrine_ping_connection: ['logs']
```

Commits
-------

d10e43d085 Allow same middleware to be used multiple times with different arguments
This commit is contained in:
Nicolas Grekas 2020-07-23 11:57:42 +02:00
commit 0d867bcc0d
2 changed files with 21 additions and 6 deletions

View File

@ -339,7 +339,7 @@ class MessengerPass implements CompilerPassInterface
if ($container->findDefinition($messengerMiddlewareId)->isAbstract()) {
$childDefinition = new ChildDefinition($messengerMiddlewareId);
$childDefinition->setArguments($arguments);
$container->setDefinition($messengerMiddlewareId = $busId.'.middleware.'.$id, $childDefinition);
$container->setDefinition($messengerMiddlewareId = $busId.'.middleware.'.$id.'.'.ContainerBuilder::hash($arguments), $childDefinition);
} elseif ($arguments) {
throw new RuntimeException(sprintf('Invalid middleware factory "%s": a middleware factory must be an abstract definition.', $id));
}

View File

@ -508,21 +508,35 @@ class MessengerPassTest extends TestCase
$container->setParameter($middlewareParameter = $fooBusId.'.middleware', [
['id' => UselessMiddleware::class],
['id' => 'middleware_with_factory', 'arguments' => ['index_0' => 'foo', 'bar']],
['id' => 'middleware_with_factory', 'arguments' => $factoryChildMiddlewareArgs1 = ['index_0' => 'foo', 'bar']],
['id' => 'middleware_with_factory', 'arguments' => $factoryChildMiddlewareArgs2 = ['index_0' => 'baz']],
['id' => 'middleware_with_factory_using_default'],
]);
(new MessengerPass())->process($container);
(new ResolveChildDefinitionsPass())->process($container);
$this->assertTrue($container->hasDefinition($factoryChildMiddlewareId = $fooBusId.'.middleware.middleware_with_factory'));
$this->assertTrue($container->hasDefinition(
$factoryChildMiddlewareArgs1Id = $fooBusId.'.middleware.middleware_with_factory.'.ContainerBuilder::hash($factoryChildMiddlewareArgs1)
));
$this->assertEquals(
['foo', 'bar'],
$container->getDefinition($factoryChildMiddlewareId)->getArguments(),
$container->getDefinition($factoryChildMiddlewareArgs1Id)->getArguments(),
'parent default argument is overridden, and next ones appended'
);
$this->assertTrue($container->hasDefinition($factoryWithDefaultChildMiddlewareId = $fooBusId.'.middleware.middleware_with_factory_using_default'));
$this->assertTrue($container->hasDefinition(
$factoryChildMiddlewareArgs2Id = $fooBusId.'.middleware.middleware_with_factory.'.ContainerBuilder::hash($factoryChildMiddlewareArgs2)
));
$this->assertEquals(
['baz'],
$container->getDefinition($factoryChildMiddlewareArgs2Id)->getArguments(),
'parent default argument is overridden, and next ones appended'
);
$this->assertTrue($container->hasDefinition(
$factoryWithDefaultChildMiddlewareId = $fooBusId.'.middleware.middleware_with_factory_using_default.'.ContainerBuilder::hash([])
));
$this->assertEquals(
['some_default'],
$container->getDefinition($factoryWithDefaultChildMiddlewareId)->getArguments(),
@ -531,7 +545,8 @@ class MessengerPassTest extends TestCase
$this->assertEquals([
new Reference(UselessMiddleware::class),
new Reference($factoryChildMiddlewareId),
new Reference($factoryChildMiddlewareArgs1Id),
new Reference($factoryChildMiddlewareArgs2Id),
new Reference($factoryWithDefaultChildMiddlewareId),
], $container->getDefinition($fooBusId)->getArgument(0)->getValues());
$this->assertFalse($container->hasParameter($middlewareParameter));