autoconfigure behavior describing tags on decorators
This commit is contained in:
parent
e5ec20400c
commit
73a3b838b7
@ -470,6 +470,14 @@ class FrameworkExtension extends Extension
|
|||||||
|
|
||||||
$container->registerForAutoconfiguration(RouteLoaderInterface::class)
|
$container->registerForAutoconfiguration(RouteLoaderInterface::class)
|
||||||
->addTag('routing.route_loader');
|
->addTag('routing.route_loader');
|
||||||
|
|
||||||
|
$container->setParameter('container.behavior_describing_tags', [
|
||||||
|
'container.service_locator',
|
||||||
|
'container.service_subscriber',
|
||||||
|
'kernel.event_subscriber',
|
||||||
|
'kernel.locale_aware',
|
||||||
|
'kernel.reset',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1656,6 +1656,20 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$this->assertSame(['redirected@example.org', 'redirected1@example.org'], $l->getArgument(1));
|
$this->assertSame(['redirected@example.org', 'redirected1@example.org'], $l->getArgument(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRegisterParameterCollectingBehaviorDescribingTags()
|
||||||
|
{
|
||||||
|
$container = $this->createContainerFromFile('default_config');
|
||||||
|
|
||||||
|
$this->assertTrue($container->hasParameter('container.behavior_describing_tags'));
|
||||||
|
$this->assertEquals([
|
||||||
|
'container.service_locator',
|
||||||
|
'container.service_subscriber',
|
||||||
|
'kernel.event_subscriber',
|
||||||
|
'kernel.locale_aware',
|
||||||
|
'kernel.reset',
|
||||||
|
], $container->getParameter('container.behavior_describing_tags'));
|
||||||
|
}
|
||||||
|
|
||||||
protected function createContainer(array $data = [])
|
protected function createContainer(array $data = [])
|
||||||
{
|
{
|
||||||
return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([
|
return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([
|
||||||
|
@ -35,16 +35,26 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$tagsToKeep = [];
|
||||||
|
|
||||||
|
if ($container->hasParameter('container.behavior_describing_tags')) {
|
||||||
|
$tagsToKeep = $container->getParameter('container.behavior_describing_tags');
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($container->getDefinitions() as $id => $definition) {
|
foreach ($container->getDefinitions() as $id => $definition) {
|
||||||
if ($definition instanceof ChildDefinition) {
|
if ($definition instanceof ChildDefinition) {
|
||||||
// don't apply "instanceof" to children: it will be applied to their parent
|
// don't apply "instanceof" to children: it will be applied to their parent
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$container->setDefinition($id, $this->processDefinition($container, $id, $definition));
|
$container->setDefinition($id, $this->processDefinition($container, $id, $definition, $tagsToKeep));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($container->hasParameter('container.behavior_describing_tags')) {
|
||||||
|
$container->getParameterBag()->remove('container.behavior_describing_tags');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processDefinition(ContainerBuilder $container, string $id, Definition $definition): Definition
|
private function processDefinition(ContainerBuilder $container, string $id, Definition $definition, array $tagsToKeep): Definition
|
||||||
{
|
{
|
||||||
$instanceofConditionals = $definition->getInstanceofConditionals();
|
$instanceofConditionals = $definition->getInstanceofConditionals();
|
||||||
$autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
|
$autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
|
||||||
@ -115,10 +125,10 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't add tags to service decorators
|
// Don't add tags to service decorators
|
||||||
if (null === $definition->getDecoratedService()) {
|
$i = \count($instanceofTags);
|
||||||
$i = \count($instanceofTags);
|
while (0 <= --$i) {
|
||||||
while (0 <= --$i) {
|
foreach ($instanceofTags[$i] as $k => $v) {
|
||||||
foreach ($instanceofTags[$i] as $k => $v) {
|
if (null === $definition->getDecoratedService() || \in_array($k, $tagsToKeep, true)) {
|
||||||
foreach ($v as $v) {
|
foreach ($v as $v) {
|
||||||
if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
|
if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -12,12 +12,16 @@
|
|||||||
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||||
|
use Symfony\Component\Config\ResourceCheckerInterface;
|
||||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
|
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
|
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
use Symfony\Contracts\Service\ResetInterface;
|
||||||
|
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
||||||
|
|
||||||
class ResolveInstanceofConditionalsPassTest extends TestCase
|
class ResolveInstanceofConditionalsPassTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -325,4 +329,60 @@ class ResolveInstanceofConditionalsPassTest extends TestCase
|
|||||||
|
|
||||||
$this->assertSame(['manual' => [[]]], $container->getDefinition('decorator')->getTags());
|
$this->assertSame(['manual' => [[]]], $container->getDefinition('decorator')->getTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDecoratorsKeepBehaviorDescribingTags()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
|
||||||
|
$container->setParameter('container.behavior_describing_tags', [
|
||||||
|
'container.service_subscriber',
|
||||||
|
'kernel.reset',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$container->register('decorator', DecoratorWithBehavior::class)
|
||||||
|
->setAutoconfigured(true)
|
||||||
|
->setDecoratedService('decorated')
|
||||||
|
;
|
||||||
|
|
||||||
|
$container->registerForAutoconfiguration(ResourceCheckerInterface::class)
|
||||||
|
->addTag('config_cache.resource_checker')
|
||||||
|
;
|
||||||
|
$container->registerForAutoconfiguration(ServiceSubscriberInterface::class)
|
||||||
|
->addTag('container.service_subscriber')
|
||||||
|
;
|
||||||
|
$container->registerForAutoconfiguration(ResetInterface::class)
|
||||||
|
->addTag('kernel.reset', ['method' => 'reset'])
|
||||||
|
;
|
||||||
|
|
||||||
|
(new ResolveInstanceofConditionalsPass())->process($container);
|
||||||
|
|
||||||
|
$this->assertEquals([
|
||||||
|
'container.service_subscriber' => [0 => []],
|
||||||
|
'kernel.reset' => [
|
||||||
|
[
|
||||||
|
'method' => 'reset',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
], $container->getDefinition('decorator')->getTags());
|
||||||
|
$this->assertFalse($container->hasParameter('container.behavior_describing_tags'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecoratorWithBehavior implements ResetInterface, ResourceCheckerInterface, ServiceSubscriberInterface
|
||||||
|
{
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supports(ResourceInterface $metadata)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isFresh(ResourceInterface $resource, $timestamp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getSubscribedServices()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user