[DI] added possibility to define services with abstract arguments
This commit is contained in:
parent
f4ff77cc08
commit
62fefaa59f
@ -0,0 +1,44 @@
|
|||||||
|
<?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\Argument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an abstract service argument, which have to be set by a compiler pass or a DI extension.
|
||||||
|
*/
|
||||||
|
final class AbstractArgument
|
||||||
|
{
|
||||||
|
private $serviceId;
|
||||||
|
private $argKey;
|
||||||
|
private $text;
|
||||||
|
|
||||||
|
public function __construct(string $serviceId, string $argKey, string $text = '')
|
||||||
|
{
|
||||||
|
$this->serviceId = $serviceId;
|
||||||
|
$this->argKey = $argKey;
|
||||||
|
$this->text = $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getServiceId(): string
|
||||||
|
{
|
||||||
|
return $this->serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getArgumentKey(): string
|
||||||
|
{
|
||||||
|
return $this->argKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getText(): string
|
||||||
|
{
|
||||||
|
return $this->text;
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ CHANGELOG
|
|||||||
|
|
||||||
* added support to autowire public typed properties in php 7.4
|
* added support to autowire public typed properties in php 7.4
|
||||||
* added support for defining method calls, a configurator, and property setters in `InlineServiceConfigurator`
|
* added support for defining method calls, a configurator, and property setters in `InlineServiceConfigurator`
|
||||||
|
* added possibility to define abstract service arguments
|
||||||
|
|
||||||
5.0.0
|
5.0.0
|
||||||
-----
|
-----
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Config\Resource\FileResource;
|
|||||||
use Symfony\Component\Config\Resource\GlobResource;
|
use Symfony\Component\Config\Resource\GlobResource;
|
||||||
use Symfony\Component\Config\Resource\ReflectionClassResource;
|
use Symfony\Component\Config\Resource\ReflectionClassResource;
|
||||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
@ -1215,6 +1216,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
$value = $this->getParameter((string) $value);
|
$value = $this->getParameter((string) $value);
|
||||||
} elseif ($value instanceof Expression) {
|
} elseif ($value instanceof Expression) {
|
||||||
$value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this]);
|
$value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this]);
|
||||||
|
} elseif ($value instanceof AbstractArgument) {
|
||||||
|
throw new RuntimeException(sprintf('Argument "%s" of service "%s" is abstract%s, did you forget to define it?', $value->getArgumentKey(), $value->getServiceId(), $value->getText() ? ' ('.$value->getText().')' : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\DependencyInjection\Dumper;
|
|||||||
|
|
||||||
use Composer\Autoload\ClassLoader;
|
use Composer\Autoload\ClassLoader;
|
||||||
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
|
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
@ -1739,6 +1740,8 @@ EOF;
|
|||||||
|
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
} elseif ($value instanceof AbstractArgument) {
|
||||||
|
throw new RuntimeException(sprintf('Argument "%s" of service "%s" is abstract%s, did you forget to define it?', $value->getArgumentKey(), $value->getServiceId(), $value->getText() ? ' ('.$value->getText().')' : ''));
|
||||||
} elseif (\is_object($value) || \is_resource($value)) {
|
} elseif (\is_object($value) || \is_resource($value)) {
|
||||||
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
|
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||||
@ -312,6 +313,14 @@ class XmlDumper extends Dumper
|
|||||||
$element->setAttribute('type', 'binary');
|
$element->setAttribute('type', 'binary');
|
||||||
$text = $this->document->createTextNode(self::phpToXml(base64_encode($value)));
|
$text = $this->document->createTextNode(self::phpToXml(base64_encode($value)));
|
||||||
$element->appendChild($text);
|
$element->appendChild($text);
|
||||||
|
} elseif ($value instanceof AbstractArgument) {
|
||||||
|
$argKey = $value->getArgumentKey();
|
||||||
|
if (!is_numeric($argKey)) {
|
||||||
|
$element->setAttribute('key', $argKey);
|
||||||
|
}
|
||||||
|
$element->setAttribute('type', 'abstract');
|
||||||
|
$text = $this->document->createTextNode(self::phpToXml($value->getText()));
|
||||||
|
$element->appendChild($text);
|
||||||
} else {
|
} else {
|
||||||
if (\in_array($value, ['null', 'true', 'false'], true)) {
|
if (\in_array($value, ['null', 'true', 'false'], true)) {
|
||||||
$element->setAttribute('type', 'string');
|
$element->setAttribute('type', 'string');
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
@ -284,6 +285,8 @@ class YamlDumper extends Dumper
|
|||||||
return $this->getExpressionCall((string) $value);
|
return $this->getExpressionCall((string) $value);
|
||||||
} elseif ($value instanceof Definition) {
|
} elseif ($value instanceof Definition) {
|
||||||
return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']);
|
return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']);
|
||||||
|
} elseif ($value instanceof AbstractArgument) {
|
||||||
|
return new TaggedValue('abstract', $value->getText());
|
||||||
} elseif (\is_object($value) || \is_resource($value)) {
|
} elseif (\is_object($value) || \is_resource($value)) {
|
||||||
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
|
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\DependencyInjection\Loader;
|
|||||||
|
|
||||||
use Symfony\Component\Config\Util\XmlUtils;
|
use Symfony\Component\Config\Util\XmlUtils;
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||||
@ -537,6 +538,10 @@ class XmlFileLoader extends FileLoader
|
|||||||
}
|
}
|
||||||
$arguments[$key] = $value;
|
$arguments[$key] = $value;
|
||||||
break;
|
break;
|
||||||
|
case 'abstract':
|
||||||
|
$serviceId = $node->getAttribute('id');
|
||||||
|
$arguments[$key] = new AbstractArgument($serviceId, (string) $key, $arg->nodeValue);
|
||||||
|
break;
|
||||||
case 'string':
|
case 'string':
|
||||||
$arguments[$key] = $arg->nodeValue;
|
$arguments[$key] = $arg->nodeValue;
|
||||||
break;
|
break;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\DependencyInjection\Loader;
|
namespace Symfony\Component\DependencyInjection\Loader;
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
@ -446,7 +447,7 @@ class YamlFileLoader extends FileLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($service['arguments'])) {
|
if (isset($service['arguments'])) {
|
||||||
$definition->setArguments($this->resolveServices($service['arguments'], $file));
|
$definition->setArguments($this->resolveServices($service['arguments'], $file, false, $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($service['properties'])) {
|
if (isset($service['properties'])) {
|
||||||
@ -722,7 +723,7 @@ class YamlFileLoader extends FileLoader
|
|||||||
*
|
*
|
||||||
* @return array|string|Reference|ArgumentInterface
|
* @return array|string|Reference|ArgumentInterface
|
||||||
*/
|
*/
|
||||||
private function resolveServices($value, string $file, bool $isParameter = false)
|
private function resolveServices($value, string $file, bool $isParameter = false, string $serviceId = '', string $argKey = '')
|
||||||
{
|
{
|
||||||
if ($value instanceof TaggedValue) {
|
if ($value instanceof TaggedValue) {
|
||||||
$argument = $value->getValue();
|
$argument = $value->getValue();
|
||||||
@ -795,13 +796,16 @@ class YamlFileLoader extends FileLoader
|
|||||||
|
|
||||||
return new Reference($id);
|
return new Reference($id);
|
||||||
}
|
}
|
||||||
|
if ('abstract' === $value->getTag()) {
|
||||||
|
return new AbstractArgument($serviceId, $argKey, $value->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag()));
|
throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\is_array($value)) {
|
if (\is_array($value)) {
|
||||||
foreach ($value as $k => $v) {
|
foreach ($value as $k => $v) {
|
||||||
$value[$k] = $this->resolveServices($v, $file, $isParameter);
|
$value[$k] = $this->resolveServices($v, $file, $isParameter, $serviceId, $k);
|
||||||
}
|
}
|
||||||
} elseif (\is_string($value) && 0 === strpos($value, '@=')) {
|
} elseif (\is_string($value) && 0 === strpos($value, '@=')) {
|
||||||
if (!class_exists(Expression::class)) {
|
if (!class_exists(Expression::class)) {
|
||||||
|
@ -260,6 +260,7 @@
|
|||||||
|
|
||||||
<xsd:simpleType name="argument_type">
|
<xsd:simpleType name="argument_type">
|
||||||
<xsd:restriction base="xsd:string">
|
<xsd:restriction base="xsd:string">
|
||||||
|
<xsd:enumeration value="abstract" />
|
||||||
<xsd:enumeration value="collection" />
|
<xsd:enumeration value="collection" />
|
||||||
<xsd:enumeration value="service" />
|
<xsd:enumeration value="service" />
|
||||||
<xsd:enumeration value="expression" />
|
<xsd:enumeration value="expression" />
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
<?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\Tests\Argument;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
|
|
||||||
|
class AbstractArgumentTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAbstractArgumentGetters()
|
||||||
|
{
|
||||||
|
$argument = new AbstractArgument('foo', '$bar', 'should be defined by Pass');
|
||||||
|
$this->assertSame('foo', $argument->getServiceId());
|
||||||
|
$this->assertSame('$bar', $argument->getArgumentKey());
|
||||||
|
$this->assertSame('should be defined by Pass', $argument->getText());
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ use Symfony\Component\Config\Resource\DirectoryResource;
|
|||||||
use Symfony\Component\Config\Resource\FileResource;
|
use Symfony\Component\Config\Resource\FileResource;
|
||||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
@ -41,6 +42,7 @@ use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
|
|||||||
use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
|
use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
|
||||||
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\SimilarArgumentsDummy;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\SimilarArgumentsDummy;
|
||||||
use Symfony\Component\DependencyInjection\TypedReference;
|
use Symfony\Component\DependencyInjection\TypedReference;
|
||||||
@ -542,6 +544,18 @@ class ContainerBuilderTest extends TestCase
|
|||||||
$this->assertEquals('foobar', $builder->get('foo')->arguments['foo']);
|
$this->assertEquals('foobar', $builder->get('foo')->arguments['foo']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCreateServiceWithAbstractArgument()
|
||||||
|
{
|
||||||
|
$this->expectException(RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('Argument "$baz" of service "foo" is abstract (should be defined by Pass), did you forget to define it?');
|
||||||
|
|
||||||
|
$builder = new ContainerBuilder();
|
||||||
|
$builder->register('foo', FooWithAbstractArgument::class)
|
||||||
|
->addArgument(new AbstractArgument('foo', '$baz', 'should be defined by Pass'));
|
||||||
|
|
||||||
|
$builder->get('foo');
|
||||||
|
}
|
||||||
|
|
||||||
public function testResolveServices()
|
public function testResolveServices()
|
||||||
{
|
{
|
||||||
$builder = new ContainerBuilder();
|
$builder = new ContainerBuilder();
|
||||||
|
@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
||||||
use Symfony\Component\Config\FileLocator;
|
use Symfony\Component\Config\FileLocator;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
@ -33,6 +34,7 @@ use Symfony\Component\DependencyInjection\ServiceLocator;
|
|||||||
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
|
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
|
use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
|
||||||
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
|
||||||
@ -1363,6 +1365,24 @@ class PhpDumperTest extends TestCase
|
|||||||
$this->assertInstanceOf(\stdClass::class, $container->get('deprecated1'));
|
$this->assertInstanceOf(\stdClass::class, $container->get('deprecated1'));
|
||||||
$this->assertInstanceOf(\stdClass::class, $container->get('deprecated2'));
|
$this->assertInstanceOf(\stdClass::class, $container->get('deprecated2'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDumpServiceWithAbstractArgument()
|
||||||
|
{
|
||||||
|
$this->expectException(RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('Argument "$baz" of service "Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument" is abstract (should be defined by Pass), did you forget to define it?');
|
||||||
|
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
|
||||||
|
$container->register(FooWithAbstractArgument::class, FooWithAbstractArgument::class)
|
||||||
|
->setArgument('$baz', new AbstractArgument(FooWithAbstractArgument::class, '$baz', 'should be defined by Pass'))
|
||||||
|
->setArgument('$bar', 'test')
|
||||||
|
->setPublic(true);
|
||||||
|
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
$dumper = new PhpDumper($container);
|
||||||
|
$dumper->dump();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Rot13EnvVarProcessor implements EnvVarProcessorInterface
|
class Rot13EnvVarProcessor implements EnvVarProcessorInterface
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Config\FileLocator;
|
use Symfony\Component\Config\FileLocator;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
@ -20,6 +21,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||||||
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
|
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
|
||||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
|
||||||
|
|
||||||
class XmlDumperTest extends TestCase
|
class XmlDumperTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -237,4 +239,15 @@ class XmlDumperTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump());
|
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDumpServiceWithAbstractArgument()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$container->register(FooWithAbstractArgument::class, FooWithAbstractArgument::class)
|
||||||
|
->setArgument('$baz', new AbstractArgument(FooWithAbstractArgument::class, '$baz', 'should be defined by Pass'))
|
||||||
|
->setArgument('$bar', 'test');
|
||||||
|
|
||||||
|
$dumper = new XmlDumper($container);
|
||||||
|
$this->assertStringEqualsFile(self::$fixturesPath.'/xml/services_with_abstract_argument.xml', $dumper->dump());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Config\FileLocator;
|
use Symfony\Component\Config\FileLocator;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
@ -21,6 +22,7 @@ use Symfony\Component\DependencyInjection\Definition;
|
|||||||
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
|
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
|
||||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
|
||||||
use Symfony\Component\Yaml\Parser;
|
use Symfony\Component\Yaml\Parser;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
@ -117,6 +119,17 @@ class YamlDumperTest extends TestCase
|
|||||||
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_tagged_argument.yml', $dumper->dump());
|
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_tagged_argument.yml', $dumper->dump());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDumpServiceWithAbstractArgument()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$container->register(FooWithAbstractArgument::class, FooWithAbstractArgument::class)
|
||||||
|
->setArgument('$baz', new AbstractArgument(FooWithAbstractArgument::class, '$baz', 'should be defined by Pass'))
|
||||||
|
->setArgument('$bar', 'test');
|
||||||
|
|
||||||
|
$dumper = new YamlDumper($container);
|
||||||
|
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_abstract_argument.yml', $dumper->dump());
|
||||||
|
}
|
||||||
|
|
||||||
private function assertEqualYamlStructure(string $expected, string $yaml, string $message = '')
|
private function assertEqualYamlStructure(string $expected, string $yaml, string $message = '')
|
||||||
{
|
{
|
||||||
$parser = new Parser();
|
$parser = new Parser();
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
|
||||||
|
|
||||||
|
class FooWithAbstractArgument
|
||||||
|
{
|
||||||
|
/** @var string */
|
||||||
|
private $baz;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $bar;
|
||||||
|
|
||||||
|
public function __construct(string $baz, string $bar)
|
||||||
|
{
|
||||||
|
$this->baz = $baz;
|
||||||
|
$this->bar = $bar;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?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="Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument">
|
||||||
|
<argument key="$baz" type="abstract">should be defined by FooCompilerPass</argument>
|
||||||
|
<argument key="$bar">test</argument>
|
||||||
|
</service>
|
||||||
|
</services>
|
||||||
|
</container>
|
@ -0,0 +1,12 @@
|
|||||||
|
<?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="Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument" class="Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument">
|
||||||
|
<argument key="$baz" type="abstract">should be defined by Pass</argument>
|
||||||
|
<argument key="$bar">test</argument>
|
||||||
|
</service>
|
||||||
|
<service id="Psr\Container\ContainerInterface" alias="service_container" public="false"/>
|
||||||
|
<service id="Symfony\Component\DependencyInjection\ContainerInterface" alias="service_container" public="false"/>
|
||||||
|
</services>
|
||||||
|
</container>
|
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
services:
|
||||||
|
service_container:
|
||||||
|
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||||
|
public: true
|
||||||
|
synthetic: true
|
||||||
|
Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument:
|
||||||
|
class: Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument
|
||||||
|
arguments: { $baz: !abstract 'should be defined by Pass', $bar: test }
|
||||||
|
Psr\Container\ContainerInterface:
|
||||||
|
alias: service_container
|
||||||
|
public: false
|
||||||
|
Symfony\Component\DependencyInjection\ContainerInterface:
|
||||||
|
alias: service_container
|
||||||
|
public: false
|
@ -16,6 +16,7 @@ use Symfony\Component\Config\FileLocator;
|
|||||||
use Symfony\Component\Config\Loader\LoaderResolver;
|
use Symfony\Component\Config\Loader\LoaderResolver;
|
||||||
use Symfony\Component\Config\Resource\FileResource;
|
use Symfony\Component\Config\Resource\FileResource;
|
||||||
use Symfony\Component\Config\Resource\GlobResource;
|
use Symfony\Component\Config\Resource\GlobResource;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||||
@ -31,6 +32,7 @@ use Symfony\Component\DependencyInjection\Reference;
|
|||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
||||||
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
|
||||||
use Symfony\Component\ExpressionLanguage\Expression;
|
use Symfony\Component\ExpressionLanguage\Expression;
|
||||||
@ -992,4 +994,15 @@ class XmlFileLoaderTest extends TestCase
|
|||||||
|
|
||||||
$this->assertSame(Prototype\SinglyImplementedInterface\Adapter\Adapter::class, (string) $alias);
|
$this->assertSame(Prototype\SinglyImplementedInterface\Adapter\Adapter::class, (string) $alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testLoadServiceWithAbstractArgument()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
|
||||||
|
$loader->load('service_with_abstract_argument.xml');
|
||||||
|
|
||||||
|
$this->assertTrue($container->hasDefinition(FooWithAbstractArgument::class));
|
||||||
|
$arguments = $container->getDefinition(FooWithAbstractArgument::class)->getArguments();
|
||||||
|
$this->assertInstanceOf(AbstractArgument::class, $arguments['$baz']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user