[DependencyInjection] added a simple way to replace a service by keeping a reference to the old one
This commit is contained in:
parent
58bed5d200
commit
1eb1f4dd73
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.5.0
|
||||
-----
|
||||
|
||||
* added DecoratorServicePass and a way to override a service definition (Definition::setDecoratedService())
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
||||
|
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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 <stof@notk.org>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
@ -46,6 +46,7 @@ class PassConfig
|
||||
|
||||
$this->optimizationPasses = array(
|
||||
new ResolveDefinitionTemplatesPass(),
|
||||
new DecoratorServicePass(),
|
||||
new ResolveParameterPlaceHoldersPass(),
|
||||
new CheckDefinitionValidityPass(),
|
||||
new ResolveReferencesToAliasesPass(),
|
||||
|
@ -38,6 +38,7 @@ class Definition
|
||||
private $abstract = false;
|
||||
private $synchronized = false;
|
||||
private $lazy = false;
|
||||
private $decoratedService;
|
||||
|
||||
protected $arguments;
|
||||
|
||||
@ -100,6 +101,31 @@ class Definition
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory method.
|
||||
*
|
||||
|
Reference in New Issue
Block a user