8000 [DependencyInjection] Add anonymous services and decorates() for flue… · symfony/symfony@55997aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 55997aa

Browse files
committed
[DependencyInjection] Add anonymous services and decorates() for fluent PHP configuration
1 parent fa1887d commit 55997aa

File tree

14 files changed

+132
-7
lines changed

14 files changed

+132
-7
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Argument;
4+
5+
6+
/**
7+
*
8+
*/
9+
final class DecoratedServiceArgument
10+
{
11+
}

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,20 @@ public function log(CompilerPassInterface $pass, $message)
14401440
$this->getCompiler()->log($pass, $message);
14411441
}
14421442

1443+
/**
1444+
* @param string $prefix
1445+
* @return string
1446+
*/
1447+
public function generateServiceName($prefix) {
1448+
$i = 0;
1449+
1450+
while ($this->hasDefinition($prefix . $i)) {
1451+
$i++;
1452+
}
1453+
1454+
return $prefix . $i;
1455+
}
1456+
14431457
/**
14441458
* Returns the Service Conditionals.
14451459
*

src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection;
1313

1414
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
15+
use Symfony\Component\DependencyInjection\Argument\DecoratedServiceArgument;
1516
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
1617
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
1718

src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

14+
use Symfony\Component\DependencyInjection\Argument\DecoratedServiceArgument;
1415
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1516
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -139,3 +140,13 @@ function expr($expression)
139140
{
140141
return new Expression($expression);
141142
}
143+
144+
/**
145+
* Placeholder for decorated service.
146+
*
147+
* @return DecoratedServiceArgument
148+
*/
149+
function decorated()
150+
{
151+
return new DecoratedServiceArgument();
152+
}

src/Symfony/Component/DependencyInjection/Loader/Configurator/ServicesConfigurator.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ final public function set($id, $class = null)
9090
return null !== $class ? $configurator->class($class) : $configurator;
9191
}
9292

93+
/**
94+
* Creates anonymous service (service without explicit name).
95+
*
96+
* @param string $class
97+
* @return ServiceConfigurator
98+
*/
99+
final public function anonymous($class)
100+
{
101+
return $this->set($this->container->generateServiceName('anon'), $class)->private();
102+
}
103+
93104
/**
94105
* Creates an alias.
95106
*

src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/ArgumentTrait.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;
1313

14+
use Symfony\Component\DependencyInjection\Argument\DecoratedServiceArgument;
15+
use Symfony\Component\DependencyInjection\Definition;
16+
use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator;
17+
18+
/**
19+
* @property string $id
20+
* @property Definition $definition
21+
*/
1422
trait ArgumentTrait
1523
{
1624
/**
@@ -22,6 +30,25 @@ trait ArgumentTrait
2230
*/
2331
final public function args(array $arguments)
2432
{
33+
$arguments = array_map(
34+
function ($argument) {
35+
if ($argument instanceof DecoratedServiceArgument) {
36+
$decorated = $this->definition->getDecoratedService();
37+
38+
if (!$decorated) {
39+
throw new \LogicException(
40+
sprintf('Specify decorates() for the "%s" service', $this->id)
41+
);
42+
}
43+
44+
return new ReferenceConfigurator($decorated[1] ? $decorated[1] : $this->id . '.inner');
45+
}
46+
47+
return $argument;
48+
},
49+
$arguments
50+
);
51+
2552
$this->definition->setArguments(static::processValue($arguments, true));
2653

2754
return $this;

src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\DependencyInjection\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15-
use Symfony\Component\DependencyInjection\Alias;
1615
use Symfony\Component\DependencyInjection\Container;
1716
use Symfony\Component\DependencyInjection\ContainerInterface;
1817
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public function testAddServiceWithoutCompilation()
144144
{
145145
$container = include self::$fixturesPath.'/containers/container9.php';
146146
$dumper = new PhpDumper($container);
147+
147148
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services9.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services');
148149
}
149150

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
6+
/**
7+
*
8+
*/
9+
final class StdClassDecorator
10+
{
11+
private $foo;
12+
private $bar;
13+
14+
public function __construct(\stdClass $foo, $bar)
15+
{
16+
$this->foo = $foo;
17+
$this->bar = $bar;
18+
}
19+
20+
public function getFoo()
21+
{
22+
return $this->foo;
23+
}
24+
25+
public function getBar()
26+
{
27+
return $this->bar;
28+
}
29+
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,11 @@
125125

126126
$s->alias('alias_for_foo', 'foo')->private()->public();
127127
$s->alias('alias_for_alias', ref('alias_for_foo'));
128+
129+
$s->anonymous('\Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator')
130+
->decorate('configured_service')
131+
->args([
132+
decorated(),
133+
42
134+
]);
128135
};

src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,13 @@
173173
$container->setAlias('alias_for_foo', 'foo')->setPublic(true);
174174
$container->setAlias('alias_for_alias', 'alias_for_foo')->setPublic(true);
175175

176+
$container
177+
->register('anon0', '\Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator')
178+
->setPublic(false)
179+
->setDecoratedService('configured_service')
180+
->setArguments([
181+
new Reference('anon0.inner'),
182+
42
183+
]);
184+
176185
return $container;

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public function getRemovedIds()
6666
return array(
6767
'Psr\\Container\\ContainerInterface' => true,
6868
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
69+
'anon0' => true,
70+
'anon0.inner' => true,
6971
'configurator_service' => true,
7072
'configurator_service_simple' => true,
7173
'decorated.pif-pouf' => true,
@@ -125,18 +127,17 @@ protected function getBazService()
125127
/**
126128
* Gets the public 'configured_service' shared service.
127129
*
128-
* @return \stdClass
130+
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator
129131
*/
130132
protected function getConfiguredServiceService()
131133
{
132134
$a = new \ConfClass();
133135
$a->setFoo(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) 10000 && false ?: '_'});
134136

135-
$this->services['configured_service'] = $instance = new \stdClass();
136-
137-
$a->configureStdClass($instance);
137+
$b = new \stdClass();
138+
$a->configureStdClass($b);
138139

139-
return $instance;
140+
return $this->services['configured_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator($b, 42);
140141
}
141142

142143
/**

src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
<service id="tagged_iterator" class="Bar" public="true">
140140
<argument type="tagged" tag="foo"/>
141141
</service>
142+
<service id="anon0" class="Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator" public="false" decorates="configured_service">
143+
<argument type="service" id="anon0.inner"/>
144+
<argument>42</argument>
145+
</service>
142146
<service id="Psr\Container\ContainerInterface" alias="service_container" public="false"/>
143147
<service id="Symfony\Component\DependencyInjection\ContainerInterface" alias="service_container" public="false"/>
144148
<service id="alias_for_foo" alias="foo" public="true"/>

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

Lines changed: 1 addition & 1 deletion
5932
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function testConfig($file)
5959
$loader->load($fixtures.'/config/'.$file.'.php');
6060

6161
$container->compile();
62-
62+
6363
$dumper = new YamlDumper($container);
6464
$this->assertStringEqualsFile($fixtures.'/config/'.$file.'.expected.yml', $dumper->dump());
6565
}

0 commit comments

Comments
 (0)
0