Skip to content

Commit 6fb5c67

Browse files
committed
[DependencyInjection] Allow manual bindings on parameters with #[Target]
1 parent a518bc2 commit 6fb5c67

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,7 @@ 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)
193-
|| $parameter->getAttributes(Target::class, \ReflectionAttribute::IS_INSTANCEOF))
192+
&& $parameter->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)
194193
) {
195194
continue;
196195
}
@@ -202,13 +201,17 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
202201
if ($typeHint && (
203202
\array_key_exists($k = preg_replace('/(^|[(|&])\\\\/', '\1', $typeHint).' $'.$name, $bindings)
204203
|| \array_key_exists($k = preg_replace('/(^|[(|&])\\\\/', '\1', $typeHint).' $'.$parsedName, $bindings)
204+
|| ($name !== $parameter->name && \array_key_exists($k = preg_replace('/(^|[(|&])\\\\/', '\1', $typeHint).' $'.$parameter->name, $bindings))
205205
)) {
206206
$arguments[$key] = $this->getBindingValue($bindings[$k]);
207207

208208
continue;
209209
}
210210

211-
if (\array_key_exists($k = '$'.$name, $bindings) || \array_key_exists($k = '$'.$parsedName, $bindings)) {
211+
if (\array_key_exists($k = '$'.$name, $bindings)
212+
|| \array_key_exists($k = '$'.$parsedName, $bindings)
213+
|| ($name !== $parameter->name && \array_key_exists($k = '$'.$parameter->name, $bindings))
214+
) {
212215
$arguments[$key] = $this->getBindingValue($bindings[$k]);
213216

214217
continue;

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
1717
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1818
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
19+
use Symfony\Component\DependencyInjection\Attribute\Target;
1920
use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass;
2021
use Symfony\Component\DependencyInjection\Compiler\DefinitionErrorExceptionPass;
2122
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
@@ -276,4 +277,44 @@ public function testAbstractArg()
276277

277278
$this->assertEquals(['C', 'K'], $definition->getArguments());
278279
}
280+
281+
public function testBindingsOnTargetedArguments()
282+
{
283+
$container = new ContainerBuilder();
284+
$container->register('service', TargetedBindingsService::class)
285+
->setAutowired(true)
286+
->setBindings([
287+
'$targetName' => 'bound_via_target',
288+
'$variableName' => 'bound_via_variable',
289+
'$commonName' => 'bound_via_common_name',
290+
]);
291+
292+
(new ResolveBindingsPass())->process($container);
293+
294+
$definition = $container->getDefinition('service');
295+
296+
// 1. Priority: Binding matches the #[Target] name
297+
$this->assertSame('bound_via_target', $definition->getArgument(0));
298+
299+
// 2. Fallback: Binding matches the variable name (Target name 'unusedTarget' has no binding)
300+
$this->assertSame('bound_via_variable', $definition->getArgument(1));
301+
302+
// 3. Equality: Target name and variable name are identical
303+
$this->assertSame('bound_via_common_name', $definition->getArgument(2));
304+
}
305+
}
306+
307+
class TargetedBindingsService
308+
{
309+
public function __construct(
310+
#[Target('targetName')]
311+
public $arg1,
312+
313+
#[Target('unusedTarget')]
314+
public $variableName,
315+
316+
#[Target('commonName')]
317+
public $commonName,
318+
) {
319+
}
279320
}

0 commit comments

Comments
 (0)