Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 165a0e2

Browse filesBrowse files
committed
Pass resolvers through a ServiceProviderInterface keyed by name
1 parent 26e0a88 commit 165a0e2
Copy full SHA for 165a0e2

File tree

Expand file treeCollapse file tree

3 files changed

+32
-20
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+32
-20
lines changed

‎src/Symfony/Component/HttpKernel/Attribute/ValueResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Attribute/ValueResolver.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
class ValueResolver
1616
{
1717
public function __construct(
18-
public readonly string $id,
18+
public readonly string $name,
1919
) {
2020
}
2121
}

‎src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php
+24-14Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\HttpKernel\Controller;
1313

14+
use Symfony\Component\DependencyInjection\ServiceLocator;
1415
use Symfony\Component\HttpFoundation\Request;
1516
use Symfony\Component\HttpKernel\Attribute\ValueResolver;
1617
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver;
@@ -21,6 +22,7 @@
2122
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\VariadicValueResolver;
2223
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
2324
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInterface;
25+
use Symfony\Contracts\Service\ServiceProviderInterface;
2426

2527
/**
2628
* Responsible for resolving the arguments passed to an action.
@@ -30,31 +32,33 @@
3032
final class ArgumentResolver implements ArgumentResolverInterface
3133
{
3234
private ArgumentMetadataFactoryInterface $argumentMetadataFactory;
33-
private iterable $argumentValueResolvers;
35+
private ServiceProviderInterface $argumentValueResolvers;
3436

3537
/**
36-
* @param iterable<mixed, ArgumentValueResolverInterface|ValueResolverInterface> $argumentValueResolvers
38+
* @param iterable<mixed, ArgumentValueResolverInterface|ValueResolverInterface>|ServiceProviderInterface<ValueResolverInterface> $argumentValueResolvers
3739
*/
38-
public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable $argumentValueResolvers = [])
40+
public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable|ServiceProviderInterface $argumentValueResolvers = [])
3941
{
4042
$this->argumentMetadataFactory = $argumentMetadataFactory ?? new ArgumentMetadataFactory();
41-
$this->argumentValueResolvers = $argumentValueResolvers ?: iterator_to_array(self::getIndexedDefaultArgumentValueResolvers());
43+
$this->argumentValueResolvers = $argumentValueResolvers instanceof ServiceProviderInterface
44+
? $argumentValueResolvers
45+
: self::getServiceProvider($argumentValueResolvers ?: self::getDefaultArgumentValueResolvers())
46+
;
4247
}
4348

4449
public function getArguments(Request $request, callable $controller, \ReflectionFunctionAbstract $reflector = null): array
4550
{
4651
$arguments = [];
52+
$resolversName = array_keys($this->argumentValueResolvers->getProvidedServices());
4753

4854
foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller, $reflector) as $metadata) {
49-
$resolverId = null;
55+
$argumentResolversName = $resolversName;
5056
if ($attributes = $metadata->getAttributesOfType(ValueResolver::class)) {
51-
$resolverId = $attributes[0]->id;
57+
$argumentResolversName = [$attributes[0]->name];
5258
}
5359

54-
foreach ($this->argumentValueResolvers as $id => $resolver) {
55-
if ($id !== ($resolverId ?? $id)) {
56-
continue;
57-
}
60+
foreach ($argumentResolversName as $resolverName) {
61+
$resolver = $this->argumentValueResolvers->get($resolverName);
5862

5963
if ((!$resolver instanceof ValueResolverInterface || $resolver instanceof TraceableValueResolver) && !$resolver->supports($request, $metadata)) {
6064
continue;
@@ -109,12 +113,18 @@ public static function getDefaultArgumentValueResolvers(): iterable
109113
}
110114

111115
/**
112-
* @return \Traversable<class-string<ValueResolverInterface>, ValueResolverInterface>
116+
* @param iterable<ArgumentValueResolverInterface|ValueResolverInterface> $resolvers
117+
*
118+
* @return ServiceProviderInterface<ArgumentValueResolverInterface|ValueResolverInterface>
113119
*/
114-
private static function getIndexedDefaultArgumentValueResolvers(): \Traversable
120+
private static function getServiceProvider(iterable $resolvers): ServiceProviderInterface
115121
{
116-
foreach (self::getDefaultArgumentValueResolvers() as $resolver) {
117-
yield $resolver::class => $resolver;
122+
$factories = [];
123+
$i = 0;
124+
foreach ($resolvers as $name => $resolver) {
125+
$factories[$name === $i++ ? $resolver::class : $name] = static fn () => $resolver;
118126
}
127+
128+
return new ServiceLocator($factories);
119129
}
120130
}

‎src/Symfony/Component/HttpKernel/DependencyInjection/ControllerArgumentValueResolverPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/DependencyInjection/ControllerArgumentValueResolverPass.php
+7-5Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212
namespace Symfony\Component\HttpKernel\DependencyInjection;
1313

14-
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
14+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
15+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
1516
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1617
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
1718
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -34,11 +35,12 @@ public function process(ContainerBuilder $container)
3435
return;
3536
}
3637

37-
$resolvers = $this->findAndSortTaggedServices('controller.argument_value_resolver', $container);
38-
$resolversId = array_map(static fn (Reference $reference) => (string) $reference, $resolvers);
38+
$iterator = new TaggedIteratorArgument('controller.argument_value_resolver', 'name');
39+
$resolvers = $this->findAndSortTaggedServices($iterator, $container);
3940

4041
if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has('debug.stopwatch')) {
41-
foreach ($resolversId as $id) {
42+
foreach ($resolvers as $resolverReference) {
43+
$id = (string) $resolverReference;
4244
$container->register("debug.$id", TraceableValueResolver::class)
4345
->setDecoratedService($id)
4446
->setArguments([new Reference("debug.$id.inner"), new Reference('debug.stopwatch')]);
@@ -47,7 +49,7 @@ public function process(ContainerBuilder $container)
4749

4850
$container
4951
->getDefinition('argument_resolver')
50-
->replaceArgument(1, new IteratorArgument(array_combine($resolversId, $resolvers)))
52+
->replaceArgument(1, new ServiceLocatorArgument($resolvers))
5153
;
5254
}
5355
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.