10000 feature #16464 [DependencyInjection] Fix some edge cases with autowir… · symfony/symfony@0e66da8 · GitHub
[go: up one dir, main page]

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)
0