feature #35076 [DI] added possibility to define services with abstract arguments (Islam93)
This PR was merged into the 5.1-dev branch.
Discussion
----------
[DI] added possibility to define services with abstract arguments
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | Fix #31769
| License | MIT
| Doc PR | n/a
feature caused by rfc #31769 from issues list
I hope, this PR will be useful
Abstract argument have to replaced by one of compiler passes or exception will be thrown.
Example:
This service definition
```xml
...
<service id="App\Test\Test">
<argument key="$a" type="abstract">should be defined by TestPass</argument>
</service>
...
```
or this for yaml
```yaml
App\Test\Test:
arguments:
$a: !abstract should be defined by TestPass
```
causes exception like `Argument "$a" of service "App\Test\Test" is abstract (should be defined by TestPass), did you forget to define it?`
if argument was not replaced by compiler pass
```php
...
public function process(ContainerBuilder $container)
{
$test = $container->getDefinition(Test::class);
$test->setArgument('$a', 'test');
}
...
```
Commits
-------
62fefaa59f
[DI] added possibility to define services with abstract arguments
This commit is contained in:
commit
e87f86b550
@ -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 for defining method calls, a configurator, and property setters in `InlineServiceConfigurator`
|
||||
* added possibility to define abstract service arguments
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Config\Resource\GlobResource;
|
||||
use Symfony\Component\Config\Resource\ReflectionClassResource;
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
@ -1215,6 +1216,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
$value = $this->getParameter((string) $value);
|
||||
} elseif ($value instanceof Expression) {
|
||||
$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;
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
@ -1739,6 +1740,8 @@ EOF;
|
||||
|
||||
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)) {
|
||||
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;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
@ -312,6 +313,14 @@ class XmlDumper extends Dumper
|
||||
$element->setAttribute('type', 'binary');
|
||||
$text = $this->document->createTextNode(self::phpToXml(base64_encode($value)));
|
||||
$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 {
|
||||
if (\in_array($value, ['null', 'true', 'false'], true)) {
|
||||
$element->setAttribute('type', 'string');
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
@ -284,6 +285,8 @@ class YamlDumper extends Dumper
|
||||
return $this->getExpressionCall((string) $value);
|
||||
} elseif ($value instanceof Definition) {
|
||||
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)) {
|
||||
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\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\ServiceLocatorArgument;
|
||||
@ -537,6 +538,10 @@ class XmlFileLoader extends FileLoader
|
||||
}
|
||||
$arguments[$key] = $value;
|
||||
break;
|
||||
case 'abstract':
|
||||
$serviceId = $node->getAttribute('id');
|
||||
$arguments[$key] = new AbstractArgument($serviceId, (string) $key, $arg->nodeValue);
|
||||
break;
|
||||
case 'string':
|
||||
$arguments[$key] = $arg->nodeValue;
|
||||
break;
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
@ -446,7 +447,7 @@ class YamlFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
if (isset($service['arguments'])) {
|
||||
$definition->setArguments($this->resolveServices($service['arguments'], $file));
|
||||
$definition->setArguments($this->resolveServices($service['arguments'], $file, false, $id));
|
||||
}
|
||||
|
||||
if (isset($service['properties'])) {
|
||||
@ -722,7 +723,7 @@ class YamlFileLoader extends FileLoader
|
||||
*
|
||||
* @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) {
|
||||
$argument = $value->getValue();
|
||||
@ -795,13 +796,16 @@ class YamlFileLoader extends FileLoader
|
||||
|
||||
return new Reference($id);
|
||||
}
|
||||
if ('abstract' === $value->getTag()) {
|
||||
return new AbstractArgument($serviceId, $argKey, $value->getValue());
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag()));
|
||||
}
|
||||
|
||||
if (\is_array($value)) {
|
||||
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, '@=')) {
|
||||
if (!class_exists(Expression::class)) {
|
||||
|
@ -260,6 +260,7 @@
|
||||
|
||||
<xsd:simpleType name="argument_type">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="abstract" />
|
||||
<xsd:enumeration value="collection" />
|
||||
<xsd:enumeration value="service" />
|
||||
<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\ResourceInterface;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
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\Fixtures\CaseSensitiveClass;
|
||||
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\SimilarArgumentsDummy;
|
||||
use Symfony\Component\DependencyInjection\TypedReference;
|
||||
@ -542,6 +544,18 @@ class ContainerBuilderTest extends TestCase
|
||||
$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()
|
||||
{
|
||||
$builder = new ContainerBuilder();
|
||||
|
@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
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\Wither;
|
||||
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\StubbedTranslator;
|
||||
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('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
|
||||
|
@ -13,6 +13,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\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
@ -20,6 +21,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
|
||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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 Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
@ -21,6 +22,7 @@ use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
|
||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
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());
|
||||
}
|
||||
|
||||
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 = '')
|
||||
{
|
||||
$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\Resource\FileResource;
|
||||
use Symfony\Component\Config\Resource\GlobResource;
|
||||
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
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\BarInterface;
|
||||
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\Prototype;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
@ -992,4 +994,15 @@ class XmlFileLoaderTest extends TestCase
|
||||
|
||||
$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