Skip to content

Commit a7bd15e

Browse files
feature #60910 [DependencyInjection] Add argument $target to ContainerBuilder::registerAliasForArgument() (nicolas-grekas)
This PR was merged into the 7.4 branch. Discussion ---------- [DependencyInjection] Add argument `$target` to `ContainerBuilder::registerAliasForArgument()` | Q | A | ------------- | --- | Branch? | 7.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | - | License | MIT This makes the API simpler and fixes `debug:autowiring`, which now displays e.g.: ``` Symfony\Component\Workflow\WorkflowInterface $commentStateMachine - target:comment - alias:state_machine.comment ``` Commits ------- 8b79ff5 [DependencyInjection] Add argument `$target` to `ContainerBuilder::registerAliasForArgument()`
2 parents 5721c68 + 8b79ff5 commit a7bd15e

File tree

10 files changed

+81
-64
lines changed

10 files changed

+81
-64
lines changed

UPGRADE-7.4.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ Console
1313

1414
* Deprecate `Symfony\Component\Console\Application::add()` in favor of `Symfony\Component\Console\Application::addCommand()`
1515

16+
DependencyInjection
17+
-------------------
18+
19+
* Add argument `$target` to `ContainerBuilder::registerAliasForArgument()`
20+
1621
FrameworkBundle
1722
---------------
1823

src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
137137
}
138138
$target = substr($id, \strlen($previousId) + 3);
139139

140-
if ($previousId.' $'.(new Target($target))->getParsedName() === $serviceId) {
140+
if ($container->findDefinition($id) === $container->findDefinition($serviceId)) {
141141
$serviceLine .= ' - <fg=magenta>target:</><fg=cyan>'.$target.'</>';
142142
break;
143143
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,8 +1190,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
11901190
// Store to container
11911191
$container->setDefinition($workflowId, $workflowDefinition);
11921192
$container->setDefinition($definitionDefinitionId, $definitionDefinition);
1193-
$container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name.'.'.$type);
1194-
$container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name);
1193+
$container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name.'.'.$type, $name);
11951194

11961195
// Add workflow to Registry
11971196
if ($workflow['supports']) {
@@ -1426,8 +1425,7 @@ private function registerAssetsConfiguration(array $config, ContainerBuilder $co
14261425
$packageDefinition = $this->createPackageDefinition($package['base_path'], $package['base_urls'], $version)
14271426
->addTag('assets.package', ['package' => $name]);
14281427
$container->setDefinition('assets._package_'.$name, $packageDefinition);
1429-
$container->registerAliasForArgument('assets._package_'.$name, PackageInterface::class, $name.'.package');
1430-
$container->registerAliasForArgument('assets._package_'.$name, PackageInterface::class, $name);
1428+
$container->registerAliasForArgument('assets._package_'.$name, PackageInterface::class, $name.'.package', $name);
14311429
}
14321430
}
14331431

@@ -2248,8 +2246,7 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
22482246
$container->setAlias('lock.factory', new Alias('lock.'.$resourceName.'.factory', false));
22492247
$container->setAlias(LockFactory::class, new Alias('lock.factory', false));
22502248
} else {
2251-
$container->registerAliasForArgument('lock.'.$resourceName.'.factory', LockFactory::class, $resourceName.'.lock.factory');
2252-
$container->registerAliasForArgument('lock.'.$resourceName.'.factory', LockFactory::class, $resourceName);
2249+
$container->registerAliasForArgument('lock.'.$resourceName.'.factory', LockFactory::class, $resourceName.'.lock.factory', $resourceName);
22532250
}
22542251
}
22552252
}
@@ -2284,8 +2281,7 @@ private function registerSemaphoreConfiguration(array $config, ContainerBuilder
22842281
$container->setAlias('semaphore.factory', new Alias('semaphore.'.$resourceName.'.factory', false));
22852282
$container->setAlias(SemaphoreFactory::class, new Alias('semaphore.factory', false));
22862283
} else {
2287-
$container->registerAliasForArgument('semaphore.'.$resourceName.'.factory', SemaphoreFactory::class, $resourceName.'.semaphore.factory');
2288-
$container->registerAliasForArgument('semaphore.'.$resourceName.'.factory', SemaphoreFactory::class, $resourceName);
2284+
$container->registerAliasForArgument('semaphore.'.$resourceName.'.factory', SemaphoreFactory::class, $resourceName.'.semaphore.factory', $resourceName);
22892285
}
22902286
}
22912287
}
@@ -3310,13 +3306,11 @@ private function registerRateLimiterConfiguration(array $config, ContainerBuilde
33103306
$factoryAlias = $container->registerAliasForArgument($limiterId, RateLimiterFactory::class, $name.'.limiter');
33113307

33123308
if (interface_exists(RateLimiterFactoryInterface::class)) {
3313-
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name.'.limiter');
3314-
$factoryAlias->setDeprecated('symfony/framework-bundle', '7.3', \sprintf('The "%%alias_id%%" autowiring alias is deprecated and will be removed in 8.0, use "%s $%s" instead.', RateLimiterFactoryInterface::class, (new Target($name.'.limiter'))->getParsedName()));
3315-
$internalAliasId = \sprintf('.%s $%s.limiter', RateLimiterFactory::class, $name);
3309+
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name.'.limiter', $name);
33163310

3317-
if ($container->hasAlias($internalAliasId)) {
3318-
$container->getAlias($internalAliasId)->setDeprecated('symfony/framework-bundle', '7.3', \sprintf('The "%%alias_id%%" autowiring alias is deprecated and will be removed in 8.0, use "%s $%s" instead.', RateLimiterFactoryInterface::class, (new Target($name.'.limiter'))->getParsedName()));
3319-
}
3311+
$factoryAlias->setDeprecated('symfony/framework-bundle', '7.3', 'The "%alias_id%" autowiring alias is deprecated and will be removed in 8.0, use "RateLimiterFactoryInterface" instead.');
3312+
$container->getAlias(\sprintf('.%s $%s.limiter', RateLimiterFactory::class, $name))
3313+
->setDeprecated('symfony/framework-bundle', '7.3', 'The "%alias_id%" autowiring alias is deprecated and will be removed in 8.0, use "RateLimiterFactoryInterface" instead.');
33203314
}
33213315
}
33223316

@@ -3341,7 +3335,7 @@ private function registerRateLimiterConfiguration(array $config, ContainerBuilde
33413335
)))
33423336
;
33433337

3344-
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name.'.limiter');
3338+
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name.'.limiter', $name);
33453339
}
33463340
}
33473341

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,11 @@ private function registerRateLimiter(ContainerBuilder $container, string $name,
120120
$factoryAlias = $container->registerAliasForArgument($limiterId, RateLimiterFactory::class, $name.'.limiter');
121121

122122
if (interface_exists(RateLimiterFactoryInterface::class)) {
123-
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name.'.limiter');
124-
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name);
125-
$factoryAlias->setDeprecated('symfony/security-bundle', '7.4', \sprintf('The "%%alias_id%%" autowiring alias is deprecated and will be removed in 8.0, use "%s $%s" instead.', RateLimiterFactoryInterface::class, (new Target($name.'.limiter'))->getParsedName()));
123+
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name.'.limiter', $name);
126124

127-
$internalAliasId = \sprintf('.%s $%s.limiter', RateLimiterFactory::class, $name);
128-
129-
if ($container->hasAlias($internalAliasId)) {
130-
$container->getAlias($internalAliasId)->setDeprecated('symfony/security-bundle', '7.4', \sprintf('The "%%alias_id%%" autowiring alias is deprecated and will be removed in 8.0, use "%s $%s" instead.', RateLimiterFactoryInterface::class, (new Target($name.'.limiter'))->getParsedName()));
131-
}
125+
$factoryAlias->setDeprecated('symfony/security-bundle', '7.4', 'The "%alias_id%" autowiring alias is deprecated and will be removed in 8.0, use "RateLimiterFactoryInterface" instead.');
126+
$container->getAlias(\sprintf('.%s $%s.limiter', RateLimiterFactory::class, $name))
127+
->setDeprecated('symfony/security-bundle', '7.4', 'The "%alias_id%" autowiring alias is deprecated and will be removed in 8.0, use "RateLimiterFactoryInterface" instead.');
132128
}
133129
}
134130
}

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Allow `#[AsAlias]` to be extended
8+
* Add argument `$target` to `ContainerBuilder::registerAliasForArgument()`
89

910
7.3
1011
---

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

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -459,30 +459,14 @@ private function getAutowiredReference(TypedReference $reference, bool $filterTy
459459
$name = $target = (array_filter($reference->getAttributes(), static fn ($a) => $a instanceof Target)[0] ?? null)?->name;
460460

461461
if (null !== $name ??= $reference->getName()) {
462-
if ($this->container->has($alias = $type.' $'.$name) && !$this->container->findDefinition($alias)->isAbstract()) {
462+
if (null !== ($alias = $this->getCombinedAlias($type, $name, $target)) && !$this->container->findDefinition($alias)->isAbstract()) {
463463
return new TypedReference($alias, $type, $reference->getInvalidBehavior());
464464
}
465465

466-
if (null !== ($alias = $this->getCombinedAlias($type, $name)) && !$this->container->findDefinition($alias)->isAbstract()) {
467-
return new TypedReference($alias, $type, $reference->getInvalidBehavior());
468-
}
469-
470-
$parsedName = (new Target($name))->getParsedName();
471-
472-
if ($this->container->has($alias = $type.' $'.$parsedName) && !$this->container->findDefinition($alias)->isAbstract()) {
473-
return new TypedReference($alias, $type, $reference->getInvalidBehavior());
474-
}
475-
476-
if (null !== ($alias = $this->getCombinedAlias($type, $parsedName)) && !$this->container->findDefinition($alias)->isAbstract()) {
477-
return new TypedReference($alias, $type, $reference->getInvalidBehavior());
478-
}
479-
480-
if (($this->container->has($n = $name) && !$this->container->findDefinition($n)->isAbstract())
481-
|| ($this->container->has($n = $parsedName) && !$this->container->findDefinition($n)->isAbstract())
482-
) {
466+
if ($this->container->has($name) && !$this->container->findDefinition($name)->isAbstract()) {
483467
foreach ($this->container->getAliases() as $id => $alias) {
484-
if ($n === (string) $alias && str_starts_with($id, $type.' $')) {
485-
return new TypedReference($n, $type, $reference->getInvalidBehavior());
468+
if ($name === (string) $alias && str_starts_with($id, $type.' $')) {
469+
return new TypedReference($name, $type, $reference->getInvalidBehavior());
486470
}
487471
}
488472
}
@@ -492,10 +476,6 @@ private function getAutowiredReference(TypedReference $reference, bool $filterTy
492476
}
493477
}
494478

495-
if ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract()) {
496-
return new TypedReference($type, $type, $reference->getInvalidBehavior());
497-
}
498-
499479
if (null !== ($alias = $this->getCombinedAlias($type)) && !$this->container->findDefinition($alias)->isAbstract()) {
500480
return new TypedReference($alias, $type, $reference->getInvalidBehavior());
501481
}
@@ -710,38 +690,43 @@ private function populateAutowiringAlias(string $id, ?string $target = null): vo
710690
$name = $m[3] ?? '';
711691

712692
if (class_exists($type, false) || interface_exists($type, false)) {
713-
if (null !== $target && str_starts_with($target, '.'.$type.' $')
714-
&& (new Target($target = substr($target, \strlen($type) + 3)))->getParsedName() === $name
715-
) {
716-
$name = $target;
693+
if (null !== $target && str_starts_with($target, '.'.$type.' $')) {
694+
$name = substr($target, \strlen($type) + 3);
717695
}
718696

719697
$this->autowiringAliases[$type][$name] = $name;
720698
}
721699
}
722700

723-
private function getCombinedAlias(string $type, ?string $name = null): ?string
701+
private function getCombinedAlias(string $type, ?string $name = null, ?string $target = null): ?string
724702
{
703+
$prefix = $target && $name ? '.' : '';
704+
$suffix = $name ? ' $'.($target ?? $name) : '';
705+
$parsedName = $target ?? ($name ? (new Target($name))->getParsedName() : null);
706+
707+
if ($this->container->has($alias = $prefix.$type.$suffix) && !$this->container->findDefinition($alias)->isAbstract()) {
708+
return $alias;
709+
}
710+
725711
if (str_contains($type, '&')) {
726712
$types = explode('&', $type);
727713
} elseif (str_contains($type, '|')) {
728714
$types = explode('|', $type);
729715
} else {
730-
return null;
716+
return $prefix || $name !== $parsedName && ($name = $parsedName) ? $this->getCombinedAlias($type, $name) : null;
731717
}
732718

733719
$alias = null;
734-
$suffix = $name ? ' $'.$name : '';
735720

736721
foreach ($types as $type) {
737-
if (!$this->container->hasAlias($type.$suffix)) {
738-
return null;
722+
if (!$this->container->hasAlias($prefix.$type.$suffix)) {
723+
return $prefix || $name !== $parsedName && ($name = $parsedName) ? $this->getCombinedAlias($type, $name) : null;
739724
}
740725

741726
if (null === $alias) {
742-
$alias = (string) $this->container->getAlias($type.$suffix);
743-
} elseif ((string) $this->container->getAlias($type.$suffix) !== $alias) {
744-
return null;
727+
$alias = (string) $this->container->getAlias($prefix.$type.$suffix);
728+
} elseif ((string) $this->container->getAlias($prefix.$type.$suffix) !== $alias) {
729+
return $prefix || $name !== $parsedName && ($name = $parsedName) ? $this->getCombinedAlias($type, $name) : null;
745730
}
746731
}
747732

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
189189
if (
190190
$value->isAutowired()
191191
&& !$value->hasTag('container.ignore_attributes')
192-
&& $parameter->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)
192+
&& ($parameter->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)
193+
|| $parameter->getAttributes(Target::class, \ReflectionAttribute::IS_INSTANCEOF))
193194
) {
194195
continue;
195196
}

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,10 +1459,13 @@ public function registerAttributeForAutoconfiguration(string $attributeClass, ca
14591459
* using camel case: "foo.bar" or "foo_bar" creates an alias bound to
14601460
* "$fooBar"-named arguments with $type as type-hint. Such arguments will
14611461
* receive the service $id when autowiring is used.
1462+
*
1463+
* @param ?string $target
14621464
*/
1463-
public function registerAliasForArgument(string $id, string $type, ?string $name = null): Alias
1465+
public function registerAliasForArgument(string $id, string $type, ?string $name = null/*, ?string $target = null */): Alias
14641466
{
14651467
$parsedName = (new Target($name ??= $id))->getParsedName();
1468+
$target = (\func_num_args() > 3 ? func_get_arg(3) : null) ?? $name;
14661469

14671470
if (!preg_match('/^[a-zA-Z_\x7f-\xff]/', $parsedName)) {
14681471
if ($id !== $name) {
@@ -1472,8 +1475,8 @@ public function registerAliasForArgument(string $id, string $type, ?string $name
14721475
throw new InvalidArgumentException(\sprintf('Invalid argument name "%s"'.$id.': the first character must be a letter.', $name));
14731476
}
14741477

1475-
if ($parsedName !== $name) {
1476-
$this->setAlias('.'.$type.' $'.$name, $type.' $'.$parsedName);
1478+
if ($parsedName !== $target) {
1479+
$this->setAlias('.'.$type.' $'.$target, $type.' $'.$parsedName);
14771480
}
14781481

14791482
return $this->setAlias($type.' $'.$parsedName, $id);

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,20 @@ public function testArgumentWithTarget()
11211121
{
11221122
$container = new ContainerBuilder();
11231123

1124+
$container->register(BarInterface::class, BarInterface::class);
1125+
$container->register('.'.BarInterface::class.' $image.storage', BarInterface::class);
1126+
$container->register('with_target', WithTarget::class)
1127+
->setAutowired(true);
1128+
1129+
(new AutowirePass())->process($container);
1130+
1131+
$this->assertSame('.'.BarInterface::class.' $image.storage', (string) $container->getDefinition('with_target')->getArgument(0));
1132+
}
1133+
1134+
public function testArgumentWithParsedTarget()
1135+
{
1136+
$container = new ContainerBuilder();
1137+
11241138
$container->register(BarInterface::class, BarInterface::class);
11251139
$container->register(BarInterface::class.' $imageStorage', BarInterface::class);
11261140
$container->register('with_target', WithTarget::class)
@@ -1161,6 +1175,20 @@ public function testArgumentWithTypoTargetAnonymous()
11611175
(new AutowirePass())->process($container);
11621176
}
11631177

1178+
public function testArgumentWithIdTarget()
1179+
{
1180+
$container = new ContainerBuilder();
1181+
1182+
$container->register('image.storage', BarInterface::class);
1183+
$container->registerAliasForArgument('image.storage', BarInterface::class, 'image');
1184+
$container->register('with_target', WithTarget::class)
1185+
->setAutowired(true);
1186+
1187+
(new AutowirePass())->process($container);
1188+
1189+
$this->assertSame('image.storage', (string) $container->getDefinition('with_target')->getArgument(0));
1190+
}
1191+
11641192
public function testDecorationWithServiceAndAliasedInterface()
11651193
{
11661194
$container = new ContainerBuilder();

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,10 @@ public function testRegisterAliasForArgument()
17791779
$container->registerAliasForArgument('Foo.bar_baz', 'Some\FooInterface', 'Bar_baz.foo');
17801780
$this->assertEquals(new Alias('Foo.bar_baz'), $container->getAlias('Some\FooInterface $barBazFoo'));
17811781
$this->assertEquals(new Alias('Some\FooInterface $barBazFoo'), $container->getAlias('.Some\FooInterface $Bar_baz.foo'));
1782+
1783+
$container->registerAliasForArgument('Foo.bar_baz', 'Some\FooInterface', 'Bar_baz.foo', 'foo');
1784+
$this->assertEquals(new Alias('Foo.bar_baz'), $container->getAlias('Some\FooInterface $barBazFoo'));
1785+
$this->assertEquals(new Alias('Some\FooInterface $barBazFoo'), $container->getAlias('.Some\FooInterface $foo'));
17821786
}
17831787

17841788
public function testCaseSensitivity()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy