bug #16642 [DI][autowiring] throw exception when many services use the same class. (aitboudad)

This PR was merged into the 2.8 branch.

Discussion
----------

[DI][autowiring] throw exception when many services use the same class.

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Fixed tickets  | #16639
| Tests pass?   | yes
| License       | MIT

Commits
-------

a21a016 [DI][autowiring] throw exception when many services use the same class.
This commit is contained in:
Fabien Potencier 2015-11-30 07:56:28 +01:00
commit 729b98c2ad
2 changed files with 63 additions and 1 deletions

View File

@ -227,7 +227,7 @@ class AutowirePass implements CompilerPassInterface
*/
private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
{
if (!$typeHint->isInstantiable()) {
if (isset($this->notGuessableTypes[$typeHint->name]) || !$typeHint->isInstantiable()) {
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s".', $typeHint->name, $id));
}

View File

@ -117,6 +117,56 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
$pass->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" for the service "a".
*/
public function testTypeNotGuessable()
{
$container = new ContainerBuilder();
$container->register('a1', __NAMESPACE__.'\Foo');
$container->register('a2', __NAMESPACE__.'\Foo');
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
$aDefinition->setAutowired(true);
$pass = new AutowirePass();
$pass->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\A" for the service "a".
*/
public function testTypeNotGuessableWithSubclass()
{
$container = new ContainerBuilder();
$container->register('a1', __NAMESPACE__.'\B');
$container->register('a2', __NAMESPACE__.'\B');
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgumentForSubclass');
$aDefinition->setAutowired(true);
$pass = new AutowirePass();
$pass->process($container);
}
public function testTypeNotGuessableWithTypeSet()
{
$container = new ContainerBuilder();
$container->register('a1', __NAMESPACE__.'\Foo');
$container->register('a2', __NAMESPACE__.'\Foo')->addAutowiringType(__NAMESPACE__.'\Foo');
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
$aDefinition->setAutowired(true);
$pass = new AutowirePass();
$pass->process($container);
$this->assertCount(1, $container->getDefinition('a')->getArguments());
$this->assertEquals('a2', (string) $container->getDefinition('a')->getArgument(0));
}
public function testWithTypeSet()
{
$container = new ContainerBuilder();
@ -335,3 +385,15 @@ class BadTypeHintedArgument
{
}
}
class NotGuessableArgument
{
public function __construct(Foo $k)
{
}
}
class NotGuessableArgumentForSubclass
{
public function __construct(A $k)
{
}
}