From 64dcd0a76ac0105d854a925c8b45b7a0efd8e033 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 12 Sep 2013 12:15:48 +0200 Subject: [PATCH] [DependencyInjection] added a simple way to replace a service by keeping a reference to the old one --- .../DependencyInjection/CHANGELOG.md | 5 ++ .../Compiler/DecoratorServicePass.php | 54 +++++++++++++++++++ .../Compiler/PassConfig.php | 1 + .../DependencyInjection/Definition.php | 26 +++++++++ 4 files changed, 86 insertions(+) create mode 100644 src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md index d3ca34c2bcb97..b47db13313543 100644 --- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md +++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.5.0 +----- + +* added DecoratorServicePass and a way to override a service definition (Definition::setDecoratedService()) + 2.4.0 ----- diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php new file mode 100644 index 0000000000000..c6db811485603 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Alias; + +/** + * Overwrites a service but keeps the overridden one. + * + * @author Christophe Coevoet + * @author Fabien Potencier + */ +class DecoratorServicePass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if (!$decorated = $definition->getDecoratedService()) { + continue; + } + + list ($decorated, $renamedId) = $decorated; + if (!$renamedId) { + $renamedId = $id.'.inner'; + } + + // we create a new alias/service for the service we are replacing + // to be able to reference it in the new one + if ($container->hasAlias($decorated)) { + $alias = $container->getAlias($decorated); + $public = $alias->isPublic(); + $container->setAlias($renamedId, new Alias((string) $alias, false)); + } else { + $definition = $container->getDefinition($decorated); + $public = $definition->isPublic(); + $definition->setPublic(false); + $container->setDefinition($renamedId, $definition); + } + + $container->setAlias($decorated, new Alias($id, $public)); + } + } +} diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php index e863f75640fb1..0ae77693ba2b5 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php @@ -50,6 +50,7 @@ public function __construct() $this->optimizationPasses = array( new ResolveDefinitionTemplatesPass(), + new DecoratorServicePass(), new ResolveParameterPlaceHoldersPass(), new CheckDefinitionValidityPass(), new ResolveReferencesToAliasesPass(), diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 1168444389ef1..e31b7ff3ad187 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -38,6 +38,7 @@ class Definition private $abstract; private $synchronized; private $lazy; + private $decoratedService; protected $arguments; @@ -64,6 +65,31 @@ public function __construct($class = null, array $arguments = array()) $this->properties = array(); } + /** + * Sets the service that this service is decorating. + * + * @param string $id The decorated service id + * @param string $renamedId The new decorated service id + */ + public function setDecoratedService($id, $renamedId = null) + { + if ($renamedId && $id == $renamedId) { + throw new \LogicException(sprintf('The decorated service parent name for "%s" must be different than the service name itself.', $id)); + } + + $this->decoratedService = array($id, $renamedId); + } + + /** + * Gets the service that decorates this service. + * + * @return array An array composed of the decorated service id and the new id for it + */ + public function getDecoratedService() + { + return $this->decoratedService; + } + /** * Sets the name of the class that acts as a factory using the factory method, * which will be invoked statically. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy