Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 398cfdd

Browse filesBrowse files
committed
[DependencyInjection] Add custom container configurators
1 parent 170ab63 commit 398cfdd
Copy full SHA for 398cfdd

File tree

5 files changed

+96
-1
lines changed
Filter options

5 files changed

+96
-1
lines changed

‎src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+36Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
2727
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
2828
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
29+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
2930
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
3031
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
3132
use Symfony\Component\Config\Resource\ClassExistenceResource;
@@ -123,6 +124,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
123124
private $removedIds = array();
124125
private $alreadyLoading = array();
125126

127+
/**
128+
* @var callable[] configurator class name => callable
129+
*/
130+
private $containerConfiguratorFactories;
131+
126132
public function __construct(ParameterBagInterface $parameterBag = null)
127133
{
128134
parent::__construct($parameterBag);
@@ -222,6 +228,36 @@ public function hasExtension($name)
222228
return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]);
223229
}
224230

231+
/**
232+
* @param callable $factory function (ContainerConfigurator $c) { .... }
233+
*/
234+
public function registerContainerConfiguratorFactory(string $configuratorClassName, callable $factory)
235+
{
236+
if (!class_exists($configuratorClassName)) {
237+
throw new \LogicException(sprintf('Container configurator class %s does not exist.', $configuratorClassName));
238+
}
239+
240+
if (isset($this->containerConfiguratorFactories[$configuratorClassName])) {
241+
throw new \LogicException(sprintf('Container configurator factory for %s was already registered.', $configuratorClassName));
242+
}
243+
244+
$this->containerConfiguratorFactories[$configuratorClassName] = $factory;
245+
}
246+
247+
/**
248+
* @param string $configuratorClassName
249+
*
250+
* @return mixed
251+
*/
252+
public function getContainerConfigurator(string $configuratorClassName, ContainerConfigurator $configurator)
253+
{
254+
if (!isset($this->containerConfiguratorFactories[$configuratorClassName])) {
255+
throw new \LogicException(sprintf('Container configurator factory for %s does not exist.', $configuratorClassName));
256+
}
257+
258+
return call_user_func($this->containerConfiguratorFactories[$configuratorClassName], $configurator);
259+
}
260+
225261
/**
226262
* Returns an array of resources loaded to build this configuration.
227263
*

‎src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php
+14-1Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,20 @@ public function load($resource, $type = null)
4444
$callback = $load($path);
4545

4646
if ($callback instanceof \Closure) {
47-
$callback(new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource), $this->container, $this);
47+
$method = new \ReflectionFunction($callback);
48+
49+
if (0 === $method->getNumberOfParameters()) {
50+
throw new \LogicException('Closure in %s:%d must have at least 1 argument.', $path, $method->getStartLine());
51+
}
52+
53+
$configurator = new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource);
54+
$configuratorClass = $method->getParameters()[0]->getClass()->name;
55+
56+
if (ContainerConfigurator::class !== $configuratorClass) {
57+
$configurator = $this->container->getContainerConfigurator($configuratorClass, $configurator);
58+
}
59+
60+
$callback($configurator, $this->container, $this);
4861
}
4962
}
5063

+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
6+
7+
final class FooContainerConfigurator
8+
{
9+
private $configurator;
10+
11+
public function __construct(ContainerConfigurator $configurator)
12+
{
13+
$this->configurator = $configurator;
14+
}
15+
16+
public function foo()
17+
{
18+
$this->configurator->parameters()->set('foo', 'bar');
19+
}
20+
}
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooContainerConfigurator;
4+
5+
return function (FooContainerConfigurator $c) {
6+
$c->foo();
7+
};

‎src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
1616
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
1717
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
18+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
1819
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
1920
use Symfony\Component\Config\FileLocator;
21+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooContainerConfigurator;
2022

2123
class PhpFileLoaderTest extends TestCase
2224
{
@@ -74,6 +76,23 @@ public function provideConfig()
7476
yield array('php7');
7577
}
7678

79+
public function testCustomContainerConfigurator()
80+
{
81+
$container = new ContainerBuilder();
82+
$container->registerContainerConfiguratorFactory(
83+
FooContainerConfigurator::class,
84+
function (ContainerConfigurator $c) {
85+
return new FooContainerConfigurator($c);
86+
}
87+
);
88+
89+
$fixtures = realpath(__DIR__.'/../Fixtures');
90+
$loader = new PhpFileLoader($container, new FileLocator());
91+
$loader->load($fixtures.'/config/custom_configurator.php');
92+
93+
$this->assertEquals('bar', $container->getParameter('foo'));
94+
}
95+
7796
/**
7897
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
7998
* @expectedExceptionMessage The service "child_service" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.