feature #10600 [DependencyInjection] added a simple way to replace a service by keeping a reference to the old one (romainneutron)
This PR was merged into the 2.5-dev branch. Discussion ---------- [DependencyInjection] added a simple way to replace a service by keeping a reference to the old one | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #5920 | License | MIT | Doc PR | https://github.com/symfony/symfony-docs/issues/3745 This PR replaces #9003. Here's the todo list: - [x] add a cookbook entry for this new feature - [x] add support in all loaders/dumpers - [x] add unit tests - [x] see if there are use cases in Symfony that would benefit from this new feature - [x] find the best name for this feature I've implemented YAML and XML Loader / Dumper. From what I see, PhpDumper, PhpLoader, IniLoader, GraphvizDumper do not require an update, am I wrong? Commits -------140f807
[DependencyInjection] Update dumpers and loaders, add unit tests1eb1f4d
[DependencyInjection] added a simple way to replace a service by keeping a reference to the old one
This commit is contained in:
commit
8ced461899
@ -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\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;
|
||||
}
|
||||
$definition->setDecoratedService(null);
|
||||
|
||||
list ($inner, $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($inner)) {
|
||||
$alias = $container->getAlias($inner);
|
||||
$public = $alias->isPublic();
|
||||
$container->setAlias($renamedId, new Alias((string) $alias, false));
|
||||
} else {
|
||||
$definition = $container->getDefinition($inner);
|
||||
$public = $definition->isPublic();
|
||||
$definition->setPublic(false);
|
||||
$container->setDefinition($renamedId, $definition);
|
||||
}
|
||||
|
||||
$container->setAlias($inner, 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,41 @@ class Definition
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service that this service is decorating.
|
||||
*
|
||||
* @param null|string $id The decorated service id, use null to remove decoration
|
||||
* @param null|string $renamedId The new decorated service id
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @throws InvalidArgumentException In case the decorated service id and the new decorated service id are equals.
|
||||
*/
|
||||
public function setDecoratedService($id, $renamedId = null)
|
||||
{
|
||||
if ($renamedId && $id == $renamedId) {
|
||||
throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
|
||||
}
|
||||
|
||||
if (null === $id) {
|
||||
$this->decoratedService = null;
|
||||
} else {
|
||||
$this->decoratedService = array($id, $renamedId);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the service that decorates this service.
|
||||
*
|
||||
* @return null|array An array composed of the decorated service id and the new id for it, null if no service is decorated
|
||||
*/
|
||||
public function getDecoratedService()
|
||||
{
|
||||
return $this->decoratedService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory method.
|
||||
*
|
||||
|
@ -138,6 +138,13 @@ class XmlDumper extends Dumper
|
||||
if ($definition->isLazy()) {
|
||||
$service->setAttribute('lazy', 'true');
|
||||
}
|
||||
if (null !== $decorated = $definition->getDecoratedService()) {
|
||||
list ($decorated, $renamedId) = $decorated;
|
||||
$service->setAttribute('decorates', $decorated);
|
||||
if (null !== $renamedId) {
|
||||
$service->setAttribute('decoration-inner-name', $renamedId);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($definition->getTags() as $name => $tags) {
|
||||
foreach ($tags as $attributes) {
|
||||
|
@ -139,6 +139,14 @@ class YamlDumper extends Dumper
|
||||
$code .= sprintf(" scope: %s\n", $scope);
|
||||
}
|
||||
|
||||
if (null !== $decorated = $definition->getDecoratedService()) {
|
||||
list ($decorated, $renamedId) = $decorated;
|
||||
$code .= sprintf(" decorates: %s\n", $decorated);
|
||||
if (null !== $renamedId) {
|
||||
$code .= sprintf(" decoration-inner-name: %s\n", $renamedId);
|
||||
}
|
||||
}
|
||||
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
if (is_array($callable)) {
|
||||
if ($callable[0] instanceof Reference) {
|
||||
|
@ -197,6 +197,11 @@ class XmlFileLoader extends FileLoader
|
||||
$definition->addTag((string) $tag['name'], $parameters);
|
||||
}
|
||||
|
||||
if (isset($service['decorates'])) {
|
||||
$renameId = isset($service['decoration-inner-name']) ? (string) $service['decoration-inner-name'] : null;
|
||||
$definition->setDecoratedService((string) $service['decorates'], $renameId);
|
||||
}
|
||||
|
||||
$this->container->setDefinition($id, $definition);
|
||||
}
|
||||
|
||||
|
@ -234,6 +234,11 @@ class YamlFileLoader extends FileLoader
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($service['decorates'])) {
|
||||
$renameId = isset($service['decoration-inner-name']) ? $service['decoration-inner-name'] : null;
|
||||
$definition->setDecoratedService($service['decorates'], $renameId);
|
||||
}
|
||||
|
||||
$this->container->setDefinition($id, $definition);
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,8 @@
|
||||
<xsd:attribute name="factory-service" type="xsd:string" />
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="parent" type="xsd:string" />
|
||||
<xsd:attribute name="decorates" type="xsd:string" />
|
||||
<xsd:attribute name="decoration-inner-name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tag">
|
||||
|
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass;
|
||||
|
||||
class DecoratorServicePassTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testProcessWithoutAlias()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$fooDefinition = $container
|
||||
->register('foo')
|
||||
->setPublic(false)
|
||||
;
|
||||
$fooExtendedDefinition = $container
|
||||
->register('foo.extended')
|
||||
->setPublic(true)
|
||||
->setDecoratedService('foo')
|
||||
;
|
||||
$barDefinition = $container
|
||||
->register('bar')
|
||||
->setPublic(true)
|
||||
;
|
||||
$barExtendedDefinition = $container
|
||||
->register('bar.extended')
|
||||
->setPublic(true)
|
||||
->setDecoratedService('bar', 'bar.yoo')
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$this->assertEquals('foo.extended', $container->getAlias('foo'));
|
||||
$this->assertFalse($container->getAlias('foo')->isPublic());
|
||||
|
||||
$this->assertEquals('bar.extended', $container->getAlias('bar'));
|
||||
$this->assertTrue($container->getAlias('bar')->isPublic());
|
||||
|
||||
$this->assertSame($fooDefinition, $container->getDefinition('foo.extended.inner'));
|
||||
$this->assertFalse($container->getDefinition('foo.extended.inner')->isPublic());
|
||||
|
||||
$this->assertSame($barDefinition, $container->getDefinition('bar.yoo'));
|
||||
$this->assertFalse($container->getDefinition('bar.yoo')->isPublic());
|
||||
|
||||
$this->assertNull($fooExtendedDefinition->getDecoratedService());
|
||||
$this->assertNull($barExtendedDefinition->getDecoratedService());
|
||||
}
|
||||
|
||||
public function testProcessWithAlias()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('foo')
|
||||
->setPublic(true)
|
||||
;
|
||||
$container->setAlias('foo.alias', new Alias('foo', false));
|
||||
$fooExtendedDefinition = $container
|
||||
->register('foo.extended')
|
||||
->setPublic(true)
|
||||
->setDecoratedService('foo.alias')
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$this->assertEquals('foo.extended', $container->getAlias('foo.alias'));
|
||||
$this->assertFalse($container->getAlias('foo.alias')->isPublic());
|
||||
|
||||
$this->assertEquals('foo', $container->getAlias('foo.extended.inner'));
|
||||
$this->assertFalse($container->getAlias('foo.extended.inner')->isPublic());
|
||||
|
||||
$this->assertNull($fooExtendedDefinition->getDecoratedService());
|
||||
}
|
||||
|
||||
protected function process(ContainerBuilder $container)
|
||||
{
|
||||
$repeatedPass = new DecoratorServicePass();
|
||||
$repeatedPass->process($container);
|
||||
}
|
||||
}
|
@ -62,6 +62,26 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('foo', $def->getClass(), '->getClass() returns the class name');
|
||||
}
|
||||
|
||||
public function testSetGetDecoratedService()
|
||||
{
|
||||
$def = new Definition('stdClass');
|
||||
$this->assertNull($def->getDecoratedService());
|
||||
$def->setDecoratedService('foo', 'foo.renamed');
|
||||
$this->assertEquals(array('foo', 'foo.renamed'), $def->getDecoratedService());
|
||||
$def->setDecoratedService(null);
|
||||
$this->assertNull($def->getDecoratedService());
|
||||
|
||||
$def = new Definition('stdClass');
|
||||
$def->setDecoratedService('foo');
|
||||
$this->assertEquals(array('foo', null), $def->getDecoratedService());
|
||||
$def->setDecoratedService(null);
|
||||
$this->assertNull($def->getDecoratedService());
|
||||
|
||||
$def = new Definition('stdClass');
|
||||
$this->setExpectedException('InvalidArgumentException', 'The decorated service inner name for "foo" must be different than the service name itself.');
|
||||
$def->setDecoratedService('foo', 'foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::setArguments
|
||||
* @covers Symfony\Component\DependencyInjection\Definition::getArguments
|
||||
|
@ -66,7 +66,7 @@ class XmlDumperTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testDumpAnonymousServices()
|
||||
{
|
||||
include self::$fixturesPath.'/containers/container11.php';
|
||||
$container = include self::$fixturesPath.'/containers/container11.php';
|
||||
$dumper = new XmlDumper($container);
|
||||
$this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?>
|
||||
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
|
||||
@ -87,7 +87,7 @@ class XmlDumperTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testDumpEntities()
|
||||
{
|
||||
include self::$fixturesPath.'/containers/container12.php';
|
||||
$container = include self::$fixturesPath.'/containers/container12.php';
|
||||
$dumper = new XmlDumper($container);
|
||||
$this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?>
|
||||
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
|
||||
@ -100,4 +100,35 @@ class XmlDumperTest extends \PHPUnit_Framework_TestCase
|
||||
</container>
|
||||
", $dumper->dump());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDecoratedServicesData
|
||||
*/
|
||||
public function testDumpDecoratedServices($expectedXmlDump, $container)
|
||||
{
|
||||
$dumper = new XmlDumper($container);
|
||||
$this->assertEquals($expectedXmlDump, $dumper->dump());
|
||||
}
|
||||
|
||||
public function provideDecoratedServicesData()
|
||||
{
|
||||
$fixturesPath = realpath(__DIR__.'/../Fixtures/');
|
||||
|
||||
return array(
|
||||
array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
|
||||
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
|
||||
<services>
|
||||
<service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\" decoration-inner-name=\"bar.woozy\"/>
|
||||
</services>
|
||||
</container>
|
||||
", include $fixturesPath.'/containers/container15.php'),
|
||||
array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
|
||||
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
|
||||
<services>
|
||||
<service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\"/>
|
||||
</services>
|
||||
</container>
|
||||
", include $fixturesPath.'/containers/container16.php'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('foo', 'FooClass\\Foo')
|
||||
->setDecoratedService('bar', 'bar.woozy')
|
||||
;
|
||||
|
||||
return $container;
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('foo', 'FooClass\\Foo')
|
||||
->setDecoratedService('bar')
|
||||
;
|
||||
|
||||
return $container;
|
@ -92,5 +92,16 @@ $container
|
||||
->register('configured_service', 'stdClass')
|
||||
->setConfigurator(array(new Reference('configurator_service'), 'configureStdClass'))
|
||||
;
|
||||
$container
|
||||
->register('decorated', 'stdClass')
|
||||
;
|
||||
$container
|
||||
->register('decorator_service', 'stdClass')
|
||||
->setDecoratedService('decorated')
|
||||
;
|
||||
$container
|
||||
->register('decorator_service_with_name', 'stdClass')
|
||||
->setDecoratedService('decorated', 'decorated.pif-pouf')
|
||||
;
|
||||
|
||||
return $container;
|
||||
|
@ -16,6 +16,9 @@ digraph sc {
|
||||
node_depends_on_request [label="depends_on_request\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
|
||||
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
|
||||
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];
|
||||
|
@ -27,6 +27,9 @@ class ProjectServiceContainer extends Container
|
||||
'baz' => 'getBazService',
|
||||
'configurator_service' => 'getConfiguratorServiceService',
|
||||
'configured_service' => 'getConfiguredServiceService',
|
||||
'decorated' => 'getDecoratedService',
|
||||
'decorator_service' => 'getDecoratorServiceService',
|
||||
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
|
||||
'depends_on_request' => 'getDependsOnRequestService',
|
||||
'factory_service' => 'getFactoryServiceService',
|
||||
'foo' => 'getFooService',
|
||||
@ -96,6 +99,45 @@ class ProjectServiceContainer extends Container
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'decorated' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return stdClass A stdClass instance.
|
||||
*/
|
||||
protected function getDecoratedService()
|
||||
{
|
||||
return $this->services['decorated'] = new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'decorator_service' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return stdClass A stdClass instance.
|
||||
*/
|
||||
protected function getDecoratorServiceService()
|
||||
{
|
||||
return $this->services['decorator_service'] = new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'decorator_service_with_name' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return stdClass A stdClass instance.
|
||||
*/
|
||||
protected function getDecoratorServiceWithNameService()
|
||||
{
|
||||
return $this->services['decorator_service_with_name'] = new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'depends_on_request' service.
|
||||
*
|
||||
|
@ -37,6 +37,8 @@ class ProjectServiceContainer extends Container
|
||||
'bar' => 'getBarService',
|
||||
'baz' => 'getBazService',
|
||||
'configured_service' => 'getConfiguredServiceService',
|
||||
'decorator_service' => 'getDecoratorServiceService',
|
||||
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
|
||||
'depends_on_request' => 'getDependsOnRequestService',
|
||||
'factory_service' => 'getFactoryServiceService',
|
||||
'foo' => 'getFooService',
|
||||
@ -49,6 +51,7 @@ class ProjectServiceContainer extends Container
|
||||
$this->aliases = array(
|
||||
'alias_for_alias' => 'foo',
|
||||
'alias_for_foo' => 'foo',
|
||||
'decorated' => 'decorator_service_with_name',
|
||||
);
|
||||
}
|
||||
|
||||
@ -108,6 +111,32 @@ class ProjectServiceContainer extends Container
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'decorator_service' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return stdClass A stdClass instance.
|
||||
*/
|
||||
protected function getDecoratorServiceService()
|
||||
{
|
||||
return $this->services['decorator_service'] = new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'decorator_service_with_name' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return stdClass A stdClass instance.
|
||||
*/
|
||||
protected function getDecoratorServiceWithNameService()
|
||||
{
|
||||
return $this->services['decorator_service_with_name'] = new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'depends_on_request' service.
|
||||
*
|
||||
|
@ -50,5 +50,7 @@
|
||||
<service id="another_alias_for_foo" alias="foo" public="false" />
|
||||
<service id="factory_service" factory-method="getInstance" factory-service="baz_factory" />
|
||||
<service id="request" class="Request" synthetic="true" synchronized="true" lazy="true"/>
|
||||
<service id="decorator_service" decorates="decorated" />
|
||||
<service id="decorator_service_with_name" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -88,6 +88,9 @@
|
||||
<service id="configured_service" class="stdClass">
|
||||
<configurator service="configurator_service" method="configureStdClass"/>
|
||||
</service>
|
||||
<service id="decorated" class="stdClass"/>
|
||||
<service id="decorator_service" class="stdClass" decorates="decorated"/>
|
||||
<service id="decorator_service_with_name" class="stdClass" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
|
||||
<service id="alias_for_foo" alias="foo"/>
|
||||
<service id="alias_for_alias" alias="foo"/>
|
||||
</services>
|
||||
|
@ -30,3 +30,8 @@ services:
|
||||
synthetic: true
|
||||
synchronized: true
|
||||
lazy: true
|
||||
decorator_service:
|
||||
decorates: decorated
|
||||
decorator_service_with_name:
|
||||
decorates: decorated
|
||||
decoration-inner-name: decorated.pif-pouf
|
||||
|
@ -79,5 +79,14 @@ services:
|
||||
configured_service:
|
||||
class: stdClass
|
||||
configurator: ['@configurator_service', configureStdClass]
|
||||
decorated:
|
||||
class: stdClass
|
||||
decorator_service:
|
||||
class: stdClass
|
||||
decorates: decorated
|
||||
decorator_service_with_name:
|
||||
class: stdClass
|
||||
decorates: decorated
|
||||
decoration-inner-name: decorated.pif-pouf
|
||||
alias_for_foo: @foo
|
||||
alias_for_alias: @foo
|
||||
|
@ -229,6 +229,10 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue(isset($aliases['another_alias_for_foo']));
|
||||
$this->assertEquals('foo', (string) $aliases['another_alias_for_foo']);
|
||||
$this->assertFalse($aliases['another_alias_for_foo']->isPublic());
|
||||
|
||||
$this->assertNull($services['request']->getDecoratedService());
|
||||
$this->assertEquals(array('decorated', null), $services['decorator_service']->getDecoratedService());
|
||||
$this->assertEquals(array('decorated', 'decorated.pif-pouf'), $services['decorator_service_with_name']->getDecoratedService());
|
||||
}
|
||||
|
||||
public function testParsesTags()
|
||||
|
@ -131,6 +131,10 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue(isset($aliases['another_alias_for_foo']));
|
||||
$this->assertEquals('foo', (string) $aliases['another_alias_for_foo']);
|
||||
$this->assertFalse($aliases['another_alias_for_foo']->isPublic());
|
||||
|
||||
$this->assertNull($services['request']->getDecoratedService());
|
||||
$this->assertEquals(array('decorated', null), $services['decorator_service']->getDecoratedService());
|
||||
$this->assertEquals(array('decorated', 'decorated.pif-pouf'), $services['decorator_service_with_name']->getDecoratedService());
|
||||
}
|
||||
|
||||
public function testExtensions()
|
||||
|
Reference in New Issue
Block a user