[DI][DX] Throw exception on some ContainerBuilder methods used from extensions
This commit is contained in:
parent
2e0cb6055f
commit
88549fff5b
@ -12,10 +12,13 @@
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\Extension\Extension;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
|
||||
/**
|
||||
* Merges extension configs into the container builder.
|
||||
@ -52,7 +55,7 @@ class MergeExtensionConfigurationPass implements CompilerPassInterface
|
||||
}
|
||||
$config = $resolvingBag->resolveValue($config);
|
||||
|
||||
$tmpContainer = new ContainerBuilder($resolvingBag);
|
||||
$tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag);
|
||||
$tmpContainer->setResourceTracking($container->isTrackingResources());
|
||||
$tmpContainer->addObjectResource($extension);
|
||||
if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
|
||||
@ -121,3 +124,44 @@ class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag
|
||||
return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A container builder preventing using methods that wouldn't have any effect from extensions.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder
|
||||
{
|
||||
private $extensionClass;
|
||||
|
||||
public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null)
|
||||
{
|
||||
parent::__construct($parameterBag);
|
||||
|
||||
$this->extensionClass = get_class($extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
|
||||
{
|
||||
throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', get_class($pass), $this->extensionClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function registerExtension(ExtensionInterface $extension)
|
||||
{
|
||||
throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', get_class($extension), $this->extensionClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile($resolveEnvPlaceholders = false)
|
||||
{
|
||||
throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass;
|
||||
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Extension\Extension;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
@ -54,6 +55,22 @@ class MergeExtensionConfigurationPassTest extends TestCase
|
||||
$this->assertEquals(array($provider), $tmpProviders);
|
||||
}
|
||||
|
||||
public function testExtensionLoadGetAMergeExtensionConfigurationContainerBuilderInstance()
|
||||
{
|
||||
$extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('load'))->getMock();
|
||||
$extension->expects($this->once())
|
||||
->method('load')
|
||||
->with($this->isType('array'), $this->isInstanceOf(MergeExtensionConfigurationContainerBuilder::class))
|
||||
;
|
||||
|
||||
$container = new ContainerBuilder(new ParameterBag());
|
||||
$container->registerExtension($extension);
|
||||
$container->prependExtensionConfig('foo', array());
|
||||
|
||||
$pass = new MergeExtensionConfigurationPass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
public function testExtensionConfigurationIsTrackedByDefault()
|
||||
{
|
||||
$extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('getConfiguration'))->getMock();
|
||||
|
Reference in New Issue
Block a user