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 9a6695c

Browse filesBrowse files
committed
feature #36389 [DI] allow decorators to reference their decorated service using the special .inner id (nicolas-grekas)
This PR was merged into the 5.1-dev branch. Discussion ---------- [DI] allow decorators to reference their decorated service using the special `.inner` id | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Right now, when one wants to decorate a service, one needs to reference the decorated service using `foo.inner`, where `foo` is the id of the decorating service. There are two issues with this IMHO: - it's weird to have to repeat the name of declaring service inside of it; - it doesn't play well with child definitions. In this PR, I propose to use `.inner` to fix both issues. Before: ```yaml services: decorating_service: arguments: [@decorating_service.inner] decorates: decorated_service ``` After: ```yaml services: decorating_service: arguments: [@.inner] decorates: decorated_service ``` Commits ------- 7b6f767 [DI] allow decorators to reference their decorated service using the special `.inner` id
2 parents c5bf92d + 7b6f767 commit 9a6695c
Copy full SHA for 9a6695c

File tree

3 files changed

+37
-1
lines changed
Filter options

3 files changed

+37
-1
lines changed

‎src/Symfony/Component/DependencyInjection/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
5.1.0
55
-----
66

7+
* allow decorators to reference their decorated service using the special `.inner` id
78
* added support to autowire public typed properties in php 7.4
89
* added support for defining method calls, a configurator, and property setters in `InlineServiceConfigurator`
910
* added possibility to define abstract service arguments

‎src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php
+21-1Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@
2424
* @author Fabien Potencier <fabien@symfony.com>
2525
* @author Diego Saint Esteben <diego@saintesteben.me>
2626
*/
27-
class DecoratorServicePass implements CompilerPassInterface
27+
class DecoratorServicePass extends AbstractRecursivePass
2828
{
29+
private $innerId = '.inner';
30+
31+
public function __construct(?string $innerId = '.inner')
32+
{
33+
$this->innerId = $innerId;
34+
}
35+
2936
public function process(ContainerBuilder $container)
3037
{
3138
$definitions = new \SplPriorityQueue();
@@ -49,6 +56,10 @@ public function process(ContainerBuilder $container)
4956
if (!$renamedId) {
5057
$renamedId = $id.'.inner';
5158
}
59+
60+
$this->currentId = $renamedId;
61+
$this->processValue($definition);
62+
5263
$definition->innerServiceId = $renamedId;
5364
$definition->decorationOnInvalid = $invalidBehavior;
5465

@@ -96,4 +107,13 @@ public function process(ContainerBuilder $container)
96107
$container->setAlias($inner, $id)->setPublic($public)->setPrivate($private);
97108
}
98109
}
110+
111+
protected function processValue($value, bool $isRoot = false)
112+
{
113+
if ($value instanceof Reference && $this->innerId === (string) $value) {
114+
return new Reference($this->currentId, $value->getInvalidBehavior());
115+
}
116+
117+
return parent::processValue($value, $isRoot);
118+
}
99119
}

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass;
1717
use Symfony\Component\DependencyInjection\ContainerBuilder;
1818
use Symfony\Component\DependencyInjection\ContainerInterface;
19+
use Symfony\Component\DependencyInjection\Reference;
1920

2021
class DecoratorServicePassTest extends TestCase
2122
{
@@ -242,6 +243,20 @@ public function testProcessLeavesServiceLocatorTagOnOriginalDefinition()
242243
$this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags());
243244
}
244245

246+
public function testGenericInnerReference()
247+
{
248+
$container = new ContainerBuilder();
249+
$container->register('foo');
250+
251+
$container->register('bar')
252+
->setDecoratedService('foo')
253+
->setProperty('prop', new Reference('.inner'));
254+
255+
$this->process($container);
256+
257+
$this->assertEquals(['prop' => new Reference('bar.inner')], $container->getDefinition('bar')->getProperties());
258+
}
259+
245260
protected function process(ContainerBuilder $container)
246261
{
247262
$pass = new DecoratorServicePass();

0 commit comments

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