feature #13761 Automatically process extensions when they implement CompilerPassInterface (WouterJ)
This PR was merged into the 2.7 branch.
Discussion
----------
Automatically process extensions when they implement CompilerPassInterface
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | todo (if people are in favor of this PR)
Compiler passes are very powerfull, but also quite strange to work with. Especially when you just need a very simple compiler pass (like https://github.com/symfony-cmf/RoutingBundle/blob/master/DependencyInjection/Compiler/SetRouterPass.php). For 3 lines of code, you need to tweak your bundle class and create a new class.
When using the DI component standalone, compiler passes are even harder to work with, as DI extensions can't register them. I believe that's why libraries like Behat make their extensions compiler passes by default.
I think it would be very easy to just implement an interface and have a `compile` method for the simple compiler pass stuff. If a bundle needs multiple compiler passes or need compiler passes to be executed at other times in the compile process, a bundle can use the normal compiler passes. But if it's just one simple thing, like replacing a definition or getting services with a specific tag, I think this method will be very usefull.
Commits
-------
6c50013
Allowed extensions to inline compiler passes
This commit is contained in:
commit
1abfaba2a5
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* A pass to automatically process extensions if they implement
|
||||
* CompilerPassInterface.
|
||||
*
|
||||
* @author Wouter J <wouter@wouterj.nl>
|
||||
*/
|
||||
class ExtensionCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($container->getExtensions() as $extension) {
|
||||
if (!$extension instanceof CompilerPassInterface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extension->process($container);
|
||||
}
|
||||
}
|
||||
}
|
@ -45,6 +45,7 @@ class PassConfig
|
||||
$this->mergePass = new MergeExtensionConfigurationPass();
|
||||
|
||||
$this->optimizationPasses = array(
|
||||
new ExtensionCompilerPass(),
|
||||
new ResolveDefinitionTemplatesPass(),
|
||||
new DecoratorServicePass(),
|
||||
new ResolveParameterPlaceHoldersPass(),
|
||||
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass;
|
||||
|
||||
/**
|
||||
* @author Wouter J <wouter@wouterj.nl>
|
||||
*/
|
||||
class ExtensionCompilerPassTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $container;
|
||||
private $pass;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder');
|
||||
$this->pass = new ExtensionCompilerPass();
|
||||
}
|
||||
|
||||
public function testProcess()
|
||||
{
|
||||
$extension1 = $this->createExtensionMock(true);
|
||||
$extension1->expects($this->once())->method('process');
|
||||
$extension2 = $this->createExtensionMock(false);
|
||||
$extension3 = $this->createExtensionMock(false);
|
||||
$extension4 = $this->createExtensionMock(true);
|
||||
$extension4->expects($this->once())->method('process');
|
||||
|
||||
$this->container->expects($this->any())
|
||||
->method('getExtensions')
|
||||
->will($this->returnValue(array($extension1, $extension2, $extension3, $extension4)))
|
||||
;
|
||||
|
||||
$this->pass->process($this->container);
|
||||
}
|
||||
|
||||
private function createExtensionMock($hasInlineCompile)
|
||||
{
|
||||
return $this->getMock('Symfony\Component\DependencyInjection\\'.(
|
||||
$hasInlineCompile
|
||||
? 'Compiler\CompilerPassInterface'
|
||||
: 'Extension\ExtensionInterface'
|
||||
));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user