10000 [DependencyInjection] added a simple way to replace a service by keep… · symfony/symfony@1eb1f4d · GitHub
[go: up one dir, main page]

Skip to content

Commit 1eb1f4d

Browse files
fabpotromainneutron
authored andcommitted
[DependencyInjection] added a simple way to replace a service by keeping a reference to the old one
1 parent 58bed5d commit 1eb1f4d

File tree

4 files changed

+86
-0
lines changed

4 files changed

+86
-0
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
2.5.0
5+
-----
6+
7+
* added DecoratorServicePass and a way to override a service definition (Definition::setDecoratedService())
8+
49
2.4.0
510
-----
611

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Alias;
17+
18+
/**
19+
* Overwrites a service but keeps the overridden one.
20+
*
21+
* @author Christophe Coevoet <stof@notk.org>
22+
* @author Fabien Potencier <fabien@symfony.com>
23+
*/
24+
class DecoratorServicePass implements CompilerPassInterface
25+
{
26+
public function process(ContainerBuilder $container)
27+
{
28+
foreach ($container->getDefinitions() as $id => $definition) {
29+
if (!$decorated = $definition->getDecoratedService()) {
30+
continue;
31+
}
32+
33+
list ($decorated, $renamedId) = $decorated;
34+
if (!$renamedId) {
35+
$renamedId = $id.'.inner';
36+
}
37+
38+
// we create a new alias/service for the service we are replacing
39+
// to be able to reference it in the new one
40+
if ($container->hasAlias($decorated)) {
41+
$alias = $container->getAlias($decorated);
42+
$public = $alias->isPublic();
43+
$container->setAlias($renamedId, new Alias((string) $alias, false));
44+
} else {
45+
$definition = $container->getDefinition($decorated);
46+
$public = $definition->isPublic();
47+
$definition->setPublic(false);
48+
$container->setDefinition($renamedId, $definition);
49+
}
50+
51+
$container->setAlias($decorated, new Alias($id, $public));
52+
}
53+
}
54+
}

src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function __construct()
4646

4747
$this->optimizationPasses = array(
4848
new ResolveDefinitionTemplatesPass(),
49+
new DecoratorServicePass(),
4950
new ResolveParameterPlaceHoldersPass(),
5051
new CheckDefinitionValidityPass(),
5152
new ResolveReferencesToAliasesPass(),

src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class Definition
3838
private $abstract = false;
3939
private $synchronized = false;
4040
private $lazy = false;
41+
private $decoratedService;
4142

4243
protected $arguments;
4344

@@ -100,6 +101,31 @@ public function setFactoryMethod($factoryMethod)
100101
return $this;
101102
}
102103

104+
/**
105+
* Sets the service that this service is decorating.
106+
*
107+
* @param string $id The decorated service id
108+
* @param string $renamedId The new decorated service id
109+
*/
110+
public function setDecoratedService($id, $renamedId = null)
111+
{
112+
if ($renamedId && $id == $renamedId) {
113+
throw new \LogicException(sprintf('The decorated service parent name for "%s" must be different than the service name itself.', $id));
114+
}
115+
116+
$this->decoratedService = array($id, $renamedId);
117+
}
118+
119+
/**
120+
* Gets the service that decorates this service.
121+
*
122+
* @return array An array composed of the decorated service id and the new id for it
123+
*/
124+
public function getDecoratedService()
125+
{
126+
return $this->decoratedService;
127+
}
128+
103129
/**
104130
* Gets the factory method.
105131
*

0 commit comments

Comments
 (0)
0