Merge branch '4.4' into 5.2
* 4.4: [DependencyInjection] fix dumping service-closure-arguments
This commit is contained in:
commit
ee75b0c54e
@ -275,9 +275,6 @@ class XmlDumper extends Dumper
|
||||
$element->setAttribute($keyAttribute, $key);
|
||||
}
|
||||
|
||||
if ($value instanceof ServiceClosureArgument) {
|
||||
$value = $value->getValues()[0];
|
||||
}
|
||||
if (\is_array($tag = $value)) {
|
||||
$element->setAttribute('type', 'collection');
|
||||
$this->convertParameters($value, $type, $element, 'key');
|
||||
@ -301,8 +298,12 @@ class XmlDumper extends Dumper
|
||||
} elseif ($value instanceof ServiceLocatorArgument) {
|
||||
$element->setAttribute('type', 'service_locator');
|
||||
$this->convertParameters($value->getValues(), $type, $element, 'key');
|
||||
} elseif ($value instanceof Reference) {
|
||||
} elseif ($value instanceof Reference || $value instanceof ServiceClosureArgument) {
|
||||
$element->setAttribute('type', 'service');
|
||||
if ($value instanceof ServiceClosureArgument) {
|
||||
$element->setAttribute('type', 'service_closure');
|
||||
$value = $value->getValues()[0];
|
||||
}
|
||||
$element->setAttribute('id', (string) $value);
|
||||
$behavior = $value->getInvalidBehavior();
|
||||
if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behavior) {
|
||||
|
@ -254,6 +254,8 @@ class YamlDumper extends Dumper
|
||||
{
|
||||
if ($value instanceof ServiceClosureArgument) {
|
||||
$value = $value->getValues()[0];
|
||||
|
||||
return new TaggedValue('service_closure', $this->getServiceCall((string) $value, $value));
|
||||
}
|
||||
if ($value instanceof ArgumentInterface) {
|
||||
$tag = $value;
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
@ -494,6 +495,13 @@ class XmlFileLoader extends FileLoader
|
||||
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="iterator" only accepts collections of type="service" references in "%s".', $name, $file));
|
||||
}
|
||||
break;
|
||||
case 'service_closure':
|
||||
if ('' === $arg->getAttribute('id')) {
|
||||
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service_closure" has no or empty "id" attribute in "%s".', $name, $file));
|
||||
}
|
||||
|
||||
$arguments[$key] = new ServiceClosureArgument(new Reference($arg->getAttribute('id'), $invalidBehavior));
|
||||
break;
|
||||
case 'service_locator':
|
||||
$arg = $this->getArgumentsAsPhp($arg, $name, $file);
|
||||
try {
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
@ -797,6 +798,15 @@ class YamlFileLoader extends FileLoader
|
||||
throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts arrays of "@service" references in "%s".', $file));
|
||||
}
|
||||
}
|
||||
if ('service_closure' === $value->getTag()) {
|
||||
$argument = $this->resolveServices($argument, $file, $isParameter);
|
||||
|
||||
if (!$argument instanceof Reference) {
|
||||
throw new InvalidArgumentException(sprintf('"!service_closure" tag only accepts service references in "%s".', $file));
|
||||
}
|
||||
|
||||
return new ServiceClosureArgument($argument);
|
||||
}
|
||||
if ('service_locator' === $value->getTag()) {
|
||||
if (!\is_array($argument)) {
|
||||
throw new InvalidArgumentException(sprintf('"!service_locator" tag only accepts maps in "%s".', $file));
|
||||
|
@ -291,6 +291,7 @@
|
||||
<xsd:enumeration value="constant" />
|
||||
<xsd:enumeration value="binary" />
|
||||
<xsd:enumeration value="iterator" />
|
||||
<xsd:enumeration value="service_closure" />
|
||||
<xsd:enumeration value="service_locator" />
|
||||
<!-- "tagged" is an alias of "tagged_iterator", using "tagged_iterator" is preferred. -->
|
||||
<xsd:enumeration value="tagged" />
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
@ -252,6 +253,17 @@ class XmlDumperTest extends TestCase
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/xml/services_with_tagged_arguments.xml', $dumper->dump());
|
||||
}
|
||||
|
||||
public function testServiceClosure()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('foo', 'Foo')
|
||||
->addArgument(new ServiceClosureArgument(new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
|
||||
;
|
||||
|
||||
$dumper = new XmlDumper($container);
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/xml/services_with_service_closure.xml', $dumper->dump());
|
||||
}
|
||||
|
||||
public function testDumpAbstractServices()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container_abstract.php';
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
@ -119,6 +120,17 @@ class YamlDumperTest extends TestCase
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_tagged_argument.yml', $dumper->dump());
|
||||
}
|
||||
|
||||
public function testServiceClosure()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('foo', 'Foo')
|
||||
->addArgument(new ServiceClosureArgument(new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
|
||||
;
|
||||
|
||||
$dumper = new YamlDumper($container);
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_service_closure.yml', $dumper->dump());
|
||||
}
|
||||
|
||||
public function testDumpServiceWithAbstractArgument()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
@ -130,6 +142,7 @@ class YamlDumperTest extends TestCase
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_abstract_argument.yml', $dumper->dump());
|
||||
}
|
||||
|
||||
|
||||
private function assertEqualYamlStructure(string $expected, string $yaml, string $message = '')
|
||||
{
|
||||
$parser = new Parser();
|
||||
|
@ -0,0 +1,15 @@
|
||||
<?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 https://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
<services>
|
||||
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
|
||||
<service id="foo" class="Foo">
|
||||
<argument type="service_closure" id="bar" on-invalid="ignore"/>
|
||||
</service>
|
||||
<service id="Psr\Container\ContainerInterface" alias="service_container">
|
||||
<deprecated package="symfony/dependency-injection" version="5.1">The "%alias_id%" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it.</deprecated>
|
||||
</service>
|
||||
<service id="Symfony\Component\DependencyInjection\ContainerInterface" alias="service_container">
|
||||
<deprecated package="symfony/dependency-injection" version="5.1">The "%alias_id%" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it.</deprecated>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
@ -0,0 +1,21 @@
|
||||
|
||||
services:
|
||||
service_container:
|
||||
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||
public: true
|
||||
synthetic: true
|
||||
foo:
|
||||
class: Foo
|
||||
arguments: [!service_closure '@?bar']
|
||||
Psr\Container\ContainerInterface:
|
||||
alias: service_container
|
||||
deprecated:
|
||||
package: symfony/dependency-injection
|
||||
version: 5.1
|
||||
message: The "%alias_id%" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it.
|
||||
Symfony\Component\DependencyInjection\ContainerInterface:
|
||||
alias: service_container
|
||||
deprecated:
|
||||
package: symfony/dependency-injection
|
||||
version: 5.1
|
||||
message: The "%alias_id%" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it.
|
@ -23,6 +23,7 @@ use Symfony\Component\Config\Util\Exception\XmlParsingException;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
|
||||
@ -381,6 +382,15 @@ class XmlFileLoaderTest extends TestCase
|
||||
$this->assertEquals(new ServiceLocatorArgument($taggedIterator), $container->getDefinition('foo_tagged_locator')->getArgument(0));
|
||||
}
|
||||
|
||||
public function testParseServiceClosure()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
|
||||
$loader->load('services_with_service_closure.xml');
|
||||
|
||||
$this->assertEquals(new ServiceClosureArgument(new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), $container->getDefinition('foo')->getArgument(0));
|
||||
}
|
||||
|
||||
public function testParseTagsWithoutNameThrowsException()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Config\Resource\GlobResource;
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
|
||||
@ -375,6 +376,15 @@ class YamlFileLoaderTest extends TestCase
|
||||
$this->assertEquals(new ServiceLocatorArgument($taggedIterator), $container->getDefinition('bar_service_tagged_locator')->getArgument(0));
|
||||
}
|
||||
|
||||
public function testParseServiceClosure()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
|
||||
$loader->load('services_with_service_closure.yml');
|
||||
|
||||
$this->assertEquals(new ServiceClosureArgument(new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), $container->getDefinition('foo')->getArgument(0));
|
||||
}
|
||||
|
||||
public function testNameOnlyTagsAreAllowedAsString()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
Reference in New Issue
Block a user