12
12
namespace Symfony \Component \HttpKernel \DependencyInjection ;
13
13
14
14
use Symfony \Bundle \FrameworkBundle \Controller \AbstractController ;
15
+ use Symfony \Component \DependencyInjection \Attribute \Autowire ;
15
16
use Symfony \Component \DependencyInjection \Attribute \Target ;
16
17
use Symfony \Component \DependencyInjection \ChildDefinition ;
17
18
use Symfony \Component \DependencyInjection \Compiler \CompilerPassInterface ;
@@ -49,6 +50,8 @@ public function process(ContainerBuilder $container)
49
50
}
50
51
}
51
52
53
+ $ emptyAutowireAttributes = class_exists (Autowire::class) ? null : [];
54
+
52
55
foreach ($ container ->findTaggedServiceIds ('controller.service_arguments ' , true ) as $ id => $ tags ) {
53
56
$ def = $ container ->getDefinition ($ id );
54
57
$ def ->setPublic (true );
@@ -122,6 +125,7 @@ public function process(ContainerBuilder $container)
122
125
/** @var \ReflectionParameter $p */
123
126
$ type = ltrim ($ target = (string ) ProxyHelper::getTypeHint ($ r , $ p ), '\\' );
124
127
$ invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE ;
128
+ $ autowireAttributes = $ autowire ? $ emptyAutowireAttributes : [];
125
129
126
130
if (isset ($ arguments [$ r ->name ][$ p ->name ])) {
127
131
$ target = $ arguments [$ r ->name ][$ p ->name ];
@@ -148,7 +152,7 @@ public function process(ContainerBuilder $container)
148
152
}
149
153
150
154
continue ;
151
- } elseif (!$ type || ! $ autowire || '\\' !== $ target [0 ]) {
155
+ } elseif (!$ autowire || (!( $ autowireAttributes ??= $ p -> getAttributes (Autowire::class)) && (! $ type || '\\' !== $ target [0 ])) ) {
152
156
continue ;
153
157
} elseif (is_subclass_of ($ type , \UnitEnum::class)) {
154
158
// do not attempt to register enum typed arguments if not already present in bindings
@@ -161,6 +165,21 @@ public function process(ContainerBuilder $container)
161
165
continue ;
162
166
}
163
167
168
+ if ($ autowireAttributes ) {
169
+ $ value = $ autowireAttributes [0 ]->newInstance ()->value ;
170
+
171
+ if ($ value instanceof Reference) {
172
+ $ args [$ p ->name ] = $ type ? new TypedReference ($ value , $ type , $ invalidBehavior , $ p ->name ) : new Reference ($ value , $ invalidBehavior );
173
+ } else {
174
+ $ args [$ p ->name ] = new Reference ('.value. ' .$ container ->hash ($ value ));
175
+ $ container ->register ((string ) $ args [$ p ->name ], 'mixed ' )
176
+ ->setFactory ('current ' )
177
+ ->addArgument ([$ value ]);
178
+ }
179
+
180
+ continue ;
181
+ }
182
+
164
183
if ($ type && !$ p ->isOptional () && !$ p ->allowsNull () && !class_exists ($ type ) && !interface_exists ($ type , false )) {
165
184
$ message = sprintf ('Cannot determine controller argument for "%s::%s()": the $%s argument is type-hinted with the non-existent class or interface: "%s". ' , $ class , $ r ->name , $ p ->name , $ type );
166
185
0 commit comments