feature #28571 [DependencyInjection] Improve ServiceLocatorTagPass service matching (codedmonkey)
This PR was squashed before being merged into the 4.2-dev branch (closes #28571).
Discussion
----------
[DependencyInjection] Improve ServiceLocatorTagPass service matching
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #26892
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/10397
Allows omitting of keys for service locator arguments (it will automatically take over the original definition alias).
Commits
-------
1c1210a3e8
[DependencyInjection] Improve ServiceLocatorTagPass service matching
This commit is contained in:
commit
104e92206c
@ -52,6 +52,12 @@ final class ServiceLocatorTagPass extends AbstractRecursivePass
|
||||
if (!$v instanceof Reference) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set, "%s" found for key "%s".', $this->currentId, \is_object($v) ? \get_class($v) : \gettype($v), $k));
|
||||
}
|
||||
|
||||
if (\is_int($k)) {
|
||||
unset($arguments[0][$k]);
|
||||
|
||||
$k = (string) $v;
|
||||
}
|
||||
$arguments[0][$k] = new ServiceClosureArgument($v);
|
||||
}
|
||||
ksort($arguments[0]);
|
||||
|
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition2;
|
||||
|
||||
require_once __DIR__.'/../Fixtures/includes/classes.php';
|
||||
|
||||
class ServiceLocatorTagPassTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage Invalid definition for service "foo": an array of references is expected as first argument when the "container.service_locator" tag is set.
|
||||
*/
|
||||
public function testNoServices()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('foo', ServiceLocator::class)
|
||||
->addTag('container.service_locator')
|
||||
;
|
||||
|
||||
(new ServiceLocatorTagPass())->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage Invalid definition for service "foo": an array of references is expected as first argument when the "container.service_locator" tag is set, "string" found for key "0".
|
||||
*/
|
||||
public function testInvalidServices()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('foo', ServiceLocator::class)
|
||||
->setArguments(array(array(
|
||||
'dummy',
|
||||
)))
|
||||
->addTag('container.service_locator')
|
||||
;
|
||||
|
||||
(new ServiceLocatorTagPass())->process($container);
|
||||
}
|
||||
|
||||
public function testProcessValue()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('bar', CustomDefinition::class);
|
||||
$container->register('baz', CustomDefinition::class);
|
||||
|
||||
$container->register('foo', ServiceLocator::class)
|
||||
->setArguments(array(array(
|
||||
new Reference('bar'),
|
||||
new Reference('baz'),
|
||||
'some.service' => new Reference('bar'),
|
||||
)))
|
||||
->addTag('container.service_locator')
|
||||
;
|
||||
|
||||
(new ServiceLocatorTagPass())->process($container);
|
||||
|
||||
/** @var ServiceLocator $locator */
|
||||
$locator = $container->get('foo');
|
||||
|
||||
$this->assertSame(CustomDefinition::class, \get_class($locator('bar')));
|
||||
$this->assertSame(CustomDefinition::class, \get_class($locator('baz')));
|
||||
$this->assertSame(CustomDefinition::class, \get_class($locator('some.service')));
|
||||
}
|
||||
|
||||
public function testServiceWithKeyOverwritesPreviousInheritedKey()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('bar', TestDefinition1::class);
|
||||
$container->register('baz', TestDefinition2::class);
|
||||
|
||||
$container->register('foo', ServiceLocator::class)
|
||||
->setArguments(array(array(
|
||||
new Reference('bar'),
|
||||
'bar' => new Reference('baz'),
|
||||
)))
|
||||
->addTag('container.service_locator')
|
||||
;
|
||||
|
||||
(new ServiceLocatorTagPass())->process($container);
|
||||
|
||||
/** @var ServiceLocator $locator */
|
||||
$locator = $container->get('foo');
|
||||
|
||||
$this->assertSame(TestDefinition2::class, \get_class($locator('bar')));
|
||||
}
|
||||
|
||||
public function testInheritedKeyOverwritesPreviousServiceWithKey()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('bar', TestDefinition1::class);
|
||||
$container->register('baz', TestDefinition2::class);
|
||||
|
||||
$container->register('foo', ServiceLocator::class)
|
||||
->setArguments(array(array(
|
||||
'bar' => new Reference('baz'),
|
||||
new Reference('bar'),
|
||||
)))
|
||||
->addTag('container.service_locator')
|
||||
;
|
||||
|
||||
(new ServiceLocatorTagPass())->process($container);
|
||||
|
||||
/** @var ServiceLocator $locator */
|
||||
$locator = $container->get('foo');
|
||||
|
||||
$this->assertSame(TestDefinition1::class, \get_class($locator('bar')));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user