bug #28159 [DI] Fix autowire inner service (hason)

This PR was merged into the 4.1 branch.

Discussion
----------

[DI] Fix autowire inner service

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #25631
| License       | MIT
| Doc PR        | -

This PR fix multiple levels of decoration. Unfortunately, this [good question](https://github.com/symfony/symfony/pull/25631#issuecomment-364610914) in origin PR has not been heard 🎧 😄. @dunglas @chalasr

Commits
-------

b79d097c2a [DI] Fix autowire inner service
This commit is contained in:
Nicolas Grekas 2018-08-08 13:48:58 +02:00
commit 441322fdc7
3 changed files with 34 additions and 3 deletions

View File

@ -144,11 +144,12 @@ class AutowirePass extends AbstractRecursivePass
*/
private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot): array
{
$this->decoratedId = null;
$this->decoratedClass = null;
$this->getPreviousValue = null;
if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && $this->container->has($this->decoratedId = $definition->innerServiceId)) {
$this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass();
} else {
$this->decoratedId = null;
$this->decoratedClass = null;
}
foreach ($this->methodCalls as $i => $call) {

View File

@ -834,6 +834,29 @@ class AutowirePassTest extends TestCase
$this->assertSame(Decorator::class.'.inner', (string) $definition->getArgument(1));
}
public function testAutowireDecoratorChain()
{
$container = new ContainerBuilder();
$container->register(LoggerInterface::class, NullLogger::class);
$container->register(Decorated::class, Decorated::class);
$container
->register(Decorator::class, Decorator::class)
->setDecoratedService(Decorated::class)
->setAutowired(true)
;
$container
->register(DecoratedDecorator::class, DecoratedDecorator::class)
->setDecoratedService(Decorated::class)
->setAutowired(true)
;
(new DecoratorServicePass())->process($container);
(new AutowirePass())->process($container);
$definition = $container->getDefinition(DecoratedDecorator::class);
$this->assertSame(DecoratedDecorator::class.'.inner', (string) $definition->getArgument(0));
}
public function testAutowireDecoratorRenamedId()
{
$container = new ContainerBuilder();

View File

@ -373,6 +373,13 @@ class Decorator implements DecoratorInterface
}
}
class DecoratedDecorator implements DecoratorInterface
{
public function __construct(DecoratorInterface $decorator)
{
}
}
class NonAutowirableDecorator implements DecoratorInterface
{
public function __construct(LoggerInterface $logger, DecoratorInterface $decorated1, DecoratorInterface $decorated2)