Skip to content

Commit 0e66da8

Browse files
committed
feature #16464 [DependencyInjection] Fix some edge cases with autowiring (dunglas)
This PR was merged into the 2.8 branch. Discussion ---------- [DependencyInjection] Fix some edge cases with autowiring | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a Enhance the autowiring system: - Works with parent definitions and decorator - Always exclude parent definitions It allows to autowire major services of the standard edition (tested with Swift Mailer, Monolog, Doctrine and Twig). Commits ------- faefc60 [DependencyInjection] Autowing: exclude abstract definitons 71d502a [DependencyInjection] Autowiring: support parent/decorators
2 parents 8c4e756 + faefc60 commit 0e66da8

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ private function populateAvailableTypes()
138138
*/
139139
private function populateAvailableType($id, Definition $definition)
140140
{
141-
if (!$definition->getClass()) {
141+
// Never use abstract services
142+
if ($definition->isAbstract()) {
142143
return;
143144
}
144145

@@ -147,6 +148,11 @@ private function populateAvailableType($id, Definition $definition)
147148
$this->types[$type] = $id;
148149
}
149150

151+
// Cannot use reflection if the class isn't set
152+
if (!$definition->getClass()) {
153+
return;
154+
}
155+
150156
if ($reflectionClass = $this->getReflectionClass($id, $definition)) {
151157
$this->extractInterfaces($id, $reflectionClass);
152158
$this->extractAncestors($id, $reflectionClass);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ private function resolveDefinition(ContainerBuilder $container, DefinitionDecora
118118
$def->setArguments($parentDef->getArguments());
119119
$def->setMethodCalls($parentDef->getMethodCalls());
120120
$def->setProperties($parentDef->getProperties());
121+
$def->setAutowiringTypes($parentDef->getAutowiringTypes());
121122
if ($parentDef->getFactoryClass(false)) {
122123
$def->setFactoryClass($parentDef->getFactoryClass(false));
123124
}
@@ -202,6 +203,11 @@ private function resolveDefinition(ContainerBuilder $container, DefinitionDecora
202203
$def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
203204
}
204205

206+
// merge autowiring types
207+
foreach ($definition->getAutowiringTypes() as $autowiringType) {
208+
$def->addAutowiringType($autowiringType);
209+
}
210+
205211
// these attributes are always taken from the child
206212
$def->setAbstract($definition->isAbstract());
207213
$def->setScope($definition->getScope(false), false);

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public function testOptionalParameter()
189189
$this->assertEquals('foo', $definition->getArgument(2));
190190
}
191191

192-
public function testDontTriggeruAutowiring()
192+
public function testDontTriggerAutowiring()
193193
{
194194
$container = new ContainerBuilder();
195195

@@ -216,6 +216,21 @@ public function testClassNotFoundThrowsException()
216216
$pass = new AutowirePass();
217217
$pass->process($container);
218218
}
219+
220+
public function testDontUseAbstractServices()
221+
{
222+
$container = new ContainerBuilder();
223+
224+
$container->register('abstract_foo', __NAMESPACE__.'\Foo')->setAbstract(true);
225+
$container->register('foo', __NAMESPACE__.'\Foo');
226+
$container->register('bar', __NAMESPACE__.'\Bar')->setAutowired(true);
227+
228+
$pass = new AutowirePass();
229+
$pass->process($container);
230+
231+
$arguments = $container->getDefinition('bar')->getArguments();
232+
$this->assertSame('foo', (string) $arguments[0]);
233+
}
219234
}
220235

221236
class Foo

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,26 @@ public function testDecoratedServiceCanOverwriteDeprecatedParentStatus()
274274
$this->assertFalse($container->getDefinition('decorated_deprecated_parent')->isDeprecated());
275275
}
276276

277+
public function testProcessMergeAutowiringTypes()
278+
{
279+
$container = new ContainerBuilder();
280+
281+
$container
282+
->register('parent')
283+
->addAutowiringType('Foo')
284+
;
285+
286+
$container
287+
->setDefinition('child', new DefinitionDecorator('parent'))
288+
->addAutowiringType('Bar')
289+
;
290+
291+
$this->process($container);
292+
293+
$def = $container->getDefinition('child');
294+
$this->assertEquals(array('Foo', 'Bar'), $def->getAutowiringTypes());
295+
}
296+
277297
protected function process(ContainerBuilder $container)
278298
{
279299
$pass = new ResolveDefinitionTemplatesPass();

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