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) {
|
||||
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);
|
||||
$serviceMap .= sprintf("\n %s => [%s, %s, %s, %s],",
|
||||
$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)),
|
||||
'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')),
|
||||
'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));
|
||||
@ -118,6 +119,7 @@ class RegisterServiceSubscribersPassTest extends TestCase
|
||||
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')),
|
||||
'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));
|
||||
@ -260,6 +262,7 @@ class RegisterServiceSubscribersPassTest extends TestCase
|
||||
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')),
|
||||
'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));
|
||||
|
@ -19,6 +19,8 @@ use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
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\ContainerInterface as SymfonyContainerInterface;
|
||||
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\ScalarFactory;
|
||||
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\TypedReference;
|
||||
use Symfony\Component\DependencyInjection\Variable;
|
||||
@ -906,6 +909,20 @@ class PhpDumperTest extends TestCase
|
||||
|
||||
$container->register(CustomDefinition::class, CustomDefinition::class)
|
||||
->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();
|
||||
|
||||
$dumper = new PhpDumper($container);
|
||||
|
@ -22,6 +22,7 @@ class TestServiceSubscriber implements ServiceSubscriberInterface
|
||||
'?'.CustomDefinition::class,
|
||||
'bar' => CustomDefinition::class,
|
||||
'baz' => '?'.CustomDefinition::class,
|
||||
'late_alias' => TestDefinition1::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,11 @@ class ProjectServiceContainer extends Container
|
||||
$this->methodMap = [
|
||||
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getTestServiceSubscriberService',
|
||||
'foo_service' => 'getFooServiceService',
|
||||
'late_alias' => 'getLateAliasService',
|
||||
];
|
||||
$this->aliases = [
|
||||
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1' => 'late_alias',
|
||||
];
|
||||
|
||||
$this->aliases = [];
|
||||
}
|
||||
|
||||
public function compile(): void
|
||||
@ -45,11 +47,13 @@ class ProjectServiceContainer extends Container
|
||||
public function getRemovedIds(): array
|
||||
{
|
||||
return [
|
||||
'.service_locator.bPEFRiK' => true,
|
||||
'.service_locator.bPEFRiK.foo_service' => true,
|
||||
'.service_locator.CpwjbIa' => true,
|
||||
'.service_locator.CpwjbIa.foo_service' => true,
|
||||
'Psr\\Container\\ContainerInterface' => true,
|
||||
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => 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],
|
||||
'bar' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', 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\\TestServiceSubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber',
|
||||
'bar' => '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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
Reference in New Issue
Block a user