bug #36454 [DependencyInjection][ServiceSubscriber] Support late aliases (fancyweb)
This PR was merged into the 4.4 branch.
Discussion
----------
[DependencyInjection][ServiceSubscriber] Support late aliases
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
A service subscriber that references a service that is aliased after optimization passes (after ResolveReferencesToAliasesPass technically) end up being dumped with the real service and not the alias.
I would consider it a bug but @nicolas-grekas told me it's a feature for him, this is why I'm submitting this on master.
@nicolas-grekas, feel free to close this one and open with your solution since you definitely know the subject better.
Commits
-------
24150370c3
[DependencyInjection][ServiceSubscriber] Support late aliases
This commit is contained in:
commit
119ba3b742
@ -1700,7 +1700,11 @@ EOF;
|
|||||||
if (!$v) {
|
if (!$v) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$definition = $this->container->findDefinition($id = (string) $v);
|
$id = (string) $v;
|
||||||
|
while ($this->container->hasAlias($id)) {
|
||||||
|
$id = (string) $this->container->getAlias($id);
|
||||||
|
}
|
||||||
|
$definition = $this->container->getDefinition($id);
|
||||||
$load = !($definition->hasErrors() && $e = $definition->getErrors()) ? $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) : reset($e);
|
$load = !($definition->hasErrors() && $e = $definition->getErrors()) ? $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) : reset($e);
|
||||||
$serviceMap .= sprintf("\n %s => [%s, %s, %s, %s],",
|
$serviceMap .= sprintf("\n %s => [%s, %s, %s, %s],",
|
||||||
$this->export($k),
|
$this->export($k),
|
||||||
|
@ -88,6 +88,7 @@ class RegisterServiceSubscribersPassTest extends TestCase
|
|||||||
CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
|
CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
|
||||||
'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
|
'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
|
||||||
'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
|
'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
|
||||||
|
'late_alias' => new ServiceClosureArgument(new TypedReference(TestDefinition1::class, TestDefinition1::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'late_alias')),
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
|
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
|
||||||
@ -118,6 +119,7 @@ class RegisterServiceSubscribersPassTest extends TestCase
|
|||||||
CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
|
CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
|
||||||
'bar' => new ServiceClosureArgument(new TypedReference('bar', CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
|
'bar' => new ServiceClosureArgument(new TypedReference('bar', CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
|
||||||
'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
|
'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
|
||||||
|
'late_alias' => new ServiceClosureArgument(new TypedReference(TestDefinition1::class, TestDefinition1::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'late_alias')),
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
|
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
|
||||||
@ -260,6 +262,7 @@ class RegisterServiceSubscribersPassTest extends TestCase
|
|||||||
CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
|
CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
|
||||||
'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
|
'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
|
||||||
'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
|
'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
|
||||||
|
'late_alias' => new ServiceClosureArgument(new TypedReference(TestDefinition1::class, TestDefinition1::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'late_alias')),
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
|
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
|
||||||
|
@ -19,6 +19,8 @@ use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
|||||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator;
|
use Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
@ -35,6 +37,7 @@ use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
|
|||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
|
||||||
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
|
||||||
use Symfony\Component\DependencyInjection\TypedReference;
|
use Symfony\Component\DependencyInjection\TypedReference;
|
||||||
use Symfony\Component\DependencyInjection\Variable;
|
use Symfony\Component\DependencyInjection\Variable;
|
||||||
@ -906,6 +909,20 @@ class PhpDumperTest extends TestCase
|
|||||||
|
|
||||||
$container->register(CustomDefinition::class, CustomDefinition::class)
|
$container->register(CustomDefinition::class, CustomDefinition::class)
|
||||||
->setPublic(false);
|
->setPublic(false);
|
||||||
|
|
||||||
|
$container->register(TestDefinition1::class, TestDefinition1::class)->setPublic(true);
|
||||||
|
|
||||||
|
$container->addCompilerPass(new class() implements CompilerPassInterface {
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function process(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
$container->setDefinition('late_alias', new Definition(TestDefinition1::class));
|
||||||
|
$container->setAlias(TestDefinition1::class, 'late_alias');
|
||||||
|
}
|
||||||
|
}, PassConfig::TYPE_AFTER_REMOVING);
|
||||||
|
|
||||||
$container->compile();
|
$container->compile();
|
||||||
|
|
||||||
$dumper = new PhpDumper($container);
|
$dumper = new PhpDumper($container);
|
||||||
|
@ -22,6 +22,7 @@ class TestServiceSubscriber implements ServiceSubscriberInterface
|
|||||||
'?'.CustomDefinition::class,
|
'?'.CustomDefinition::class,
|
||||||
'bar' => CustomDefinition::class,
|
'bar' => CustomDefinition::class,
|
||||||
'baz' => '?'.CustomDefinition::class,
|
'baz' => '?'.CustomDefinition::class,
|
||||||
|
'late_alias' => TestDefinition1::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,11 @@ class ProjectServiceContainer extends Container
|
|||||||
$this->methodMap = [
|
$this->methodMap = [
|
||||||
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getTestServiceSubscriberService',
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getTestServiceSubscriberService',
|
||||||
'foo_service' => 'getFooServiceService',
|
'foo_service' => 'getFooServiceService',
|
||||||
|
'late_alias' => 'getLateAliasService',
|
||||||
|
];
|
||||||
|
$this->aliases = [
|
||||||
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1' => 'late_alias',
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->aliases = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function compile(): void
|
public function compile(): void
|
||||||
@ -45,11 +47,13 @@ class ProjectServiceContainer extends Container
|
|||||||
public function getRemovedIds(): array
|
public function getRemovedIds(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'.service_locator.bPEFRiK' => true,
|
'.service_locator.CpwjbIa' => true,
|
||||||
'.service_locator.bPEFRiK.foo_service' => true,
|
'.service_locator.CpwjbIa.foo_service' => true,
|
||||||
'Psr\\Container\\ContainerInterface' => true,
|
'Psr\\Container\\ContainerInterface' => true,
|
||||||
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
||||||
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,
|
||||||
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1' => true,
|
||||||
|
'late_alias' => true,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,14 +79,26 @@ class ProjectServiceContainer extends Container
|
|||||||
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false],
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false],
|
||||||
'bar' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false],
|
'bar' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false],
|
||||||
'baz' => ['privates', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'getCustomDefinitionService', false],
|
'baz' => ['privates', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'getCustomDefinitionService', false],
|
||||||
|
'late_alias' => ['services', 'late_alias', 'getLateAliasService', false],
|
||||||
], [
|
], [
|
||||||
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
|
||||||
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber',
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber',
|
||||||
'bar' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
|
'bar' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
|
||||||
'baz' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
|
'baz' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
|
||||||
|
'late_alias' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1',
|
||||||
]))->withContext('foo_service', $this));
|
]))->withContext('foo_service', $this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the public 'late_alias' shared service.
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1
|
||||||
|
*/
|
||||||
|
protected function getLateAliasService()
|
||||||
|
{
|
||||||
|
return $this->services['late_alias'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared service.
|
* Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared service.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user