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 definitons71d502a
[DependencyInjection] Autowiring: support parent/decorators
This commit is contained in:
commit
0e66da8abb
@ -138,7 +138,8 @@ class AutowirePass implements CompilerPassInterface
|
||||
*/
|
||||
private function populateAvailableType($id, Definition $definition)
|
||||
{
|
||||
if (!$definition->getClass()) {
|
||||
// Never use abstract services
|
||||
if ($definition->isAbstract()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,6 +148,11 @@ class AutowirePass implements CompilerPassInterface
|
||||
$this->types[$type] = $id;
|
||||
}
|
||||
|
||||
// Cannot use reflection if the class isn't set
|
||||
if (!$definition->getClass()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($reflectionClass = $this->getReflectionClass($id, $definition)) {
|
||||
$this->extractInterfaces($id, $reflectionClass);
|
||||
$this->extractAncestors($id, $reflectionClass);
|
||||
|
@ -118,6 +118,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
$def->setArguments($parentDef->getArguments());
|
||||
$def->setMethodCalls($parentDef->getMethodCalls());
|
||||
$def->setProperties($parentDef->getProperties());
|
||||
$def->setAutowiringTypes($parentDef->getAutowiringTypes());
|
||||
if ($parentDef->getFactoryClass(false)) {
|
||||
$def->setFactoryClass($parentDef->getFactoryClass(false));
|
||||
}
|
||||
@ -202,6 +203,11 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
$def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
|
||||
}
|
||||
|
||||
// merge autowiring types
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringType) {
|
||||
$def->addAutowiringType($autowiringType);
|
||||
}
|
||||
|
||||
// these attributes are always taken from the child
|
||||
$def->setAbstract($definition->isAbstract());
|
||||
$def->setScope($definition->getScope(false), false);
|
||||
|
@ -189,7 +189,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('foo', $definition->getArgument(2));
|
||||
}
|
||||
|
||||
public function testDontTriggeruAutowiring()
|
||||
public function testDontTriggerAutowiring()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
@ -216,6 +216,21 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
$pass = new AutowirePass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
public function testDontUseAbstractServices()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('abstract_foo', __NAMESPACE__.'\Foo')->setAbstract(true);
|
||||
$container->register('foo', __NAMESPACE__.'\Foo');
|
||||
$container->register('bar', __NAMESPACE__.'\Bar')->setAutowired(true);
|
||||
|
||||
$pass = new AutowirePass();
|
||||
$pass->process($container);
|
||||
|
||||
$arguments = $container->getDefinition('bar')->getArguments();
|
||||
$this->assertSame('foo', (string) $arguments[0]);
|
||||
}
|
||||
}
|
||||
|
||||
class Foo
|
||||
|
@ -274,6 +274,26 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($container->getDefinition('decorated_deprecated_parent')->isDeprecated());
|
||||
}
|
||||
|
||||
public function testProcessMergeAutowiringTypes()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container
|
||||
->register('parent')
|
||||
->addAutowiringType('Foo')
|
||||
;
|
||||
|
||||
$container
|
||||
->setDefinition('child', new DefinitionDecorator('parent'))
|
||||
->addAutowiringType('Bar')
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$def = $container->getDefinition('child');
|
||||
$this->assertEquals(array('Foo', 'Bar'), $def->getAutowiringTypes());
|
||||
}
|
||||
|
||||
protected function process(ContainerBuilder $container)
|
||||
{
|
||||
$pass = new ResolveDefinitionTemplatesPass();
|
||||
|
Reference in New Issue
Block a user