8000 bug #42019 [DependencyInjection] Fix TaggedLocator attribute without … · symfony/symfony@e33714b · GitHub
[go: up one dir, main page]

Skip to content

Commit e33714b

Browse files
bug #42019 [DependencyInjection] Fix TaggedLocator attribute without indexAttribute argument (Lucas Bäuerle)
This PR was merged into the 5.3 branch. Discussion ---------- [DependencyInjection] Fix TaggedLocator attribute without indexAttribute argument | Q | A | ------------- | --- | Branch? | 5.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | | License | MIT | Doc PR | The new TaggedLocator attribute does not index services correctly without the `indexAttribute` argument ## Example ```php public function __construct( #[TaggedLocator('app.tag')] ServiceLocator $serviceLocator ) { // ... } ``` ### Expected ```php $serviceLocator->getProvidedServices(); // [ // "App\Service1" => "..." // "App\Service2" => "..." // ] $serviceLocator->has(App\Service1::class); // true $serviceLocator->get(App\Service1::class); // Instance of App\Service1 ``` ### Actual ```php $services = $serviceLocator->getProvidedServices(); // [ // 0 => [...] // 1 => [...] // ] $serviceLocator->has(App\Service1::class); // false $serviceLocator->get(App\Service1::class); // Exception ``` Same issue with ContainerInterface instead of ServiceLocator ## Proposed solution This fix allows services to be indexed by their fully qualified name instead of a numeric index if `indexAttribute` argument is not provided. The solution is oriented towards the implemenation in the YamlFileLoader (Symfony\Component\DependencyInjection\Loader\YamlFileLoader). The YamlFileLoader fulfills the expected behaviour above: ```php // Symfony\Component\DependencyInjection\Loader\YamlFileLoader // Line 850 $forLocator = 'tagged_locator' === $value->getTag(); // ... // Line 857 $argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null); ``` Commits ------- 0499fff [DependencyInjection] Fix TaggedLocator attribute without index argument
2 parents 888cf5c + 0499fff commit e33714b

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
218218

219219
if (TaggedLocator::class === $attribute->getName()) {
220220
$attribute = $attribute->newInstance();
221-
$arguments[$index] = new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute));
221+
$arguments[$index] = new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, null, true));
222222
break;
223223
}
224224
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumer;
3333
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerConsumer;
3434
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerFactory;
35+
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithoutIndex;
3536
use Symfony\Component\DependencyInjection\Tests\Fixtures\TaggedService1;
3637
use Symfony\Component\DependencyInjection\Tests\Fixtures\TaggedService2;
3738
use Symfony\Component\DependencyInjection\Tests\Fixtures\TaggedService3;
@@ -403,6 +404,35 @@ public function testTaggedLocatorConfiguredViaAttribute()
403404
self::assertSame($container->get(FooTagClass::class), $locator->get('foo'));
404405
}
405406

407+
/**
408+
* @requires PHP 8
409+
*/
410+
public function testTaggedLocatorConfiguredViaAttributeWithoutIndex()
411+
{
412+
$container = new ContainerBuilder();
413+
$container->register(BarTagClass::class)
414+
->setPublic(true)
415+
->addTag('foo_bar')
416+
;
417+
$container->register(FooTagClass::class)
418+
->setPublic(true)
419+
->addTag('foo_bar')
420+
;
421+
$container->register(LocatorConsumerWithoutIndex::class)
422+
->setAutowired(true)
423+
->setPublic(true)
424+
;
425+
426+
$container->compile();
427+
428+
/** @var LocatorConsumerWithoutIndex $s */
429+
$s = $container->get(LocatorConsumerWithoutIndex::class);
430+
431+
$locator = $s->getLocator();
432+
self::assertSame($container->get(BarTagClass::class), $locator->get(BarTagClass::class));
433+
self::assertSame($container->get(FooTagClass::class), $locator->get(FooTagClass::class));
434+
}
435+
406436
/**
407437
* @requires PHP 8
408438
*/
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
16+
17+
final class LocatorConsumerWithoutIndex
18+
{
19+
public function __construct(
20+
#[TaggedLocator('foo_bar')]
21+
private ContainerInterface $locator,
22+
) {
23+
}
24+
25+
public function getLocator(): ContainerInterface
26+
{
27+
return $this->locator;
28+
}
29+
}

0 commit comments

Comments
 (0)
0