feature #21383 [DependencyInjection] Add support for named arguments (dunglas, nicolas-grekas)
This PR was merged into the 3.3-dev branch. Discussion ---------- [DependencyInjection] Add support for named arguments | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | todo This PR introduces named arguments for services definitions. It's especially useful to inject parameters in an autowired service. It is (at least partially) an alternative to #21376 and #20738. Usage: ```yml services: _defaults: { autowire: true } Acme\NewsletterManager: { $apiKey: "%mandrill_api_key%" } # Alternative (traditional) syntax services: newsletter_manager: class: Acme\NewsletterManager arguments: $apiKey: "%mandrill_api_key%" autowire: true ``` ```php use Doctrine\ORM\EntityManager; use Psr\Log\LoggerInterface; namespace Acme; class NewsletterManager { private $logger; private $em; private $apiKey; public function __construct(LoggerInterface $logger, EntityManager $em, $apiKey) { $this->logger = $logger; $this->em = $em; $this->apiKey = $apiKey; } } ``` Commits -------8a126c8537
[DI] Deprecate string keys in arguments2ce36a6074
[DependencyInjection] Add a new pass to check arguments validity6e501296f9
[DependencyInjection] Add support for named arguments
This commit is contained in:
commit
9ac3a7e010
@ -213,12 +213,14 @@ class ChildDefinition extends Definition
|
||||
*/
|
||||
public function replaceArgument($index, $value)
|
||||
{
|
||||
if (!is_int($index)) {
|
||||
if (is_int($index)) {
|
||||
$this->arguments['index_'.$index] = $value;
|
||||
} elseif (0 === strpos($index, '$')) {
|
||||
$this->arguments[$index] = $value;
|
||||
} else {
|
||||
throw new InvalidArgumentException('$index must be an integer.');
|
||||
}
|
||||
|
||||
$this->arguments['index_'.$index] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
<?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\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Checks if arguments of methods are properly configured.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CheckArgumentsValidityPass extends AbstractRecursivePass
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
foreach ($value->getArguments() as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
if (!is_int($k)) {
|
||||
throw new RuntimeException(sprintf('Invalid constructor argument for service "%s": integer expected but found string "%s". Check your service definition.', $this->currentId, $k));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Invalid constructor argument %d for service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $this->currentId, $i));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($value->getMethodCalls() as $methodCall) {
|
||||
$i = 0;
|
||||
foreach ($methodCall[1] as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
if (!is_int($k)) {
|
||||
throw new RuntimeException(sprintf('Invalid argument for method call "%s" of service "%s": integer expected but found string "%s". Check your service definition.', $methodCall[0], $this->currentId, $k));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Invalid argument %d for method call "%s" of service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $methodCall[0], $this->currentId, $i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -53,12 +53,14 @@ class PassConfig
|
||||
new ResolveFactoryClassPass(),
|
||||
new FactoryReturnTypePass($resolveClassPass),
|
||||
new CheckDefinitionValidityPass(),
|
||||
new ResolveNamedArgumentsPass(),
|
||||
new AutowirePass(),
|
||||
new ResolveReferencesToAliasesPass(),
|
||||
new ResolveInvalidReferencesPass(),
|
||||
new AnalyzeServiceReferencesPass(true),
|
||||
new CheckCircularReferencesPass(),
|
||||
new CheckReferenceValidityPass(),
|
||||
new CheckArgumentsValidityPass(),
|
||||
));
|
||||
|
||||
$this->removingPasses = array(array(
|
||||
|
@ -145,11 +145,12 @@ class ResolveDefinitionTemplatesPass extends AbstractRecursivePass
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 !== strpos($k, 'index_')) {
|
||||
if (0 === strpos($k, 'index_')) {
|
||||
$index = (int) substr($k, strlen('index_'));
|
||||
} elseif (0 !== strpos($k, '$')) {
|
||||
throw new RuntimeException(sprintf('Invalid argument key "%s" found.', $k));
|
||||
}
|
||||
|
||||
$index = (int) substr($k, strlen('index_'));
|
||||
$def->replaceArgument($index, $v);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,117 @@
|
||||
<?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\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Resolves named arguments to their corresponding numeric index.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ResolveNamedArgumentsPass extends AbstractRecursivePass
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$parameterBag = $this->container->getParameterBag();
|
||||
|
||||
if ($class = $value->getClass()) {
|
||||
$class = $parameterBag->resolveValue($class);
|
||||
}
|
||||
|
||||
$calls = $value->getMethodCalls();
|
||||
$calls[] = array('__construct', $value->getArguments());
|
||||
|
||||
foreach ($calls as $i => $call) {
|
||||
list($method, $arguments) = $call;
|
||||
$method = $parameterBag->resolveValue($method);
|
||||
$parameters = null;
|
||||
$resolvedArguments = array();
|
||||
|
||||
foreach ($arguments as $key => $argument) {
|
||||
if (is_int($key) || '' === $key || '$' !== $key[0]) {
|
||||
if (!is_int($key)) {
|
||||
@trigger_error(sprintf('Using key "%s" for defining arguments of method "%s" for service "%s" is deprecated since Symfony 3.3 and will throw an exception in 4.0. Use no keys or $named arguments instead.', $key, $method, $this->currentId), E_USER_DEPRECATED);
|
||||
}
|
||||
$resolvedArguments[] = $argument;
|
||||
continue;
|
||||
}
|
||||
|
||||
$parameters = null !== $parameters ? $parameters : $this->getParameters($class, $method);
|
||||
|
||||
foreach ($parameters as $j => $p) {
|
||||
if ($key === '$'.$p->name) {
|
||||
$resolvedArguments[$j] = $argument;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Unable to resolve service "%s": method "%s::%s" has no argument named "%s". Check your service definition.', $this->currentId, $class, $method, $key));
|
||||
}
|
||||
|
||||
if ($resolvedArguments !== $call[1]) {
|
||||
ksort($resolvedArguments);
|
||||
$calls[$i][1] = $resolvedArguments;
|
||||
}
|
||||
}
|
||||
|
||||
list(, $arguments) = array_pop($calls);
|
||||
|
||||
if ($arguments !== $value->getArguments()) {
|
||||
$value->setArguments($arguments);
|
||||
}
|
||||
if ($calls !== $value->getMethodCalls()) {
|
||||
$value->setMethodCalls($calls);
|
||||
}
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $class
|
||||
* @param string $method
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getParameters($class, $method)
|
||||
{
|
||||
if (!$class) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to resolve service "%s": the class is not set.', $this->currentId));
|
||||
}
|
||||
|
||||
if (!$r = $this->container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to resolve service "%s": class "%s" does not exist.', $this->currentId, $class));
|
||||
}
|
||||
|
||||
if (!$r->hasMethod($method)) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to resolve service "%s": method "%s::%s" does not exist.', $this->currentId, $class, $method));
|
||||
}
|
||||
|
||||
$method = $r->getMethod($method);
|
||||
if (!$method->isPublic()) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to resolve service "%s": method "%s::%s" must be public.', $this->currentId, $class, $method->name));
|
||||
}
|
||||
|
||||
return $method->getParameters();
|
||||
}
|
||||
}
|
@ -190,8 +190,8 @@ class Definition
|
||||
/**
|
||||
* Sets a specific argument.
|
||||
*
|
||||
* @param int $index
|
||||
* @param mixed $argument
|
||||
* @param int|string $index
|
||||
* @param mixed $argument
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
@ -203,10 +203,14 @@ class Definition
|
||||
throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.');
|
||||
}
|
||||
|
||||
if ($index < 0 || $index > count($this->arguments) - 1) {
|
||||
if (is_int($index) && ($index < 0 || $index > count($this->arguments) - 1)) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
|
||||
}
|
||||
|
||||
if (!array_key_exists($index, $this->arguments)) {
|
||||
throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
|
||||
}
|
||||
|
||||
$this->arguments[$index] = $argument;
|
||||
|
||||
return $this;
|
||||
@ -225,7 +229,7 @@ class Definition
|
||||
/**
|
||||
* Gets an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param int $index
|
||||
* @param int|string $index
|
||||
*
|
||||
* @return mixed The argument value
|
||||
*
|
||||
@ -233,8 +237,8 @@ class Definition
|
||||
*/
|
||||
public function getArgument($index)
|
||||
{
|
||||
if ($index < 0 || $index > count($this->arguments) - 1) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
|
||||
if (!array_key_exists($index, $this->arguments)) {
|
||||
throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
|
||||
}
|
||||
|
||||
return $this->arguments[$index];
|
||||
|
@ -254,6 +254,22 @@ class YamlFileLoader extends FileLoader
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $service
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isUsingShortSyntax(array $service)
|
||||
{
|
||||
foreach ($service as $key => $value) {
|
||||
if (is_string($key) && ('' === $key || '$' !== $key[0])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a definition.
|
||||
*
|
||||
@ -273,7 +289,7 @@ class YamlFileLoader extends FileLoader
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array($service) && array_values($service) === $service) {
|
||||
if (is_array($service) && $this->isUsingShortSyntax($service)) {
|
||||
$service = array('arguments' => $service);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
<?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\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CheckArgumentsValidityPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class CheckArgumentsValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testProcess()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$definition = $container->register('foo');
|
||||
$definition->setArguments(array(null, 1, 'a'));
|
||||
$definition->setMethodCalls(array(
|
||||
array('bar', array('a', 'b')),
|
||||
array('baz', array('c', 'd')),
|
||||
));
|
||||
|
||||
$pass = new CheckArgumentsValidityPass();
|
||||
$pass->process($container);
|
||||
|
||||
$this->assertEquals(array(null, 1, 'a'), $container->getDefinition('foo')->getArguments());
|
||||
$this->assertEquals(array(
|
||||
array('bar', array('a', 'b')),
|
||||
array('baz', array('c', 'd')),
|
||||
), $container->getDefinition('foo')->getMethodCalls());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @dataProvider definitionProvider
|
||||
*/
|
||||
public function testException(array $arguments, array $methodCalls)
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$definition = $container->register('foo');
|
||||
$definition->setArguments($arguments);
|
||||
$definition->setMethodCalls($methodCalls);
|
||||
|
||||
$pass = new CheckArgumentsValidityPass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
public function definitionProvider()
|
||||
{
|
||||
return array(
|
||||
array(array(null, 'a' => 'a'), array()),
|
||||
array(array(1 => 1), array()),
|
||||
array(array(), array(array('baz', array(null, 'a' => 'a')))),
|
||||
array(array(), array(array('baz', array(1 => 1)))),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
<?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\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\ResolveNamedArgumentsPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ResolveNamedArgumentsPassTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testProcess()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class);
|
||||
$definition->setArguments(array(0 => new Reference('foo'), '$apiKey' => '123'));
|
||||
$definition->addMethodCall('setApiKey', array('$apiKey' => '123'));
|
||||
|
||||
$pass = new ResolveNamedArgumentsPass();
|
||||
$pass->process($container);
|
||||
|
||||
$this->assertEquals(array(0 => new Reference('foo'), 1 => '123'), $definition->getArguments());
|
||||
$this->assertEquals(array(array('setApiKey', array('123'))), $definition->getMethodCalls());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testClassNull()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$definition = $container->register(NamedArgumentsDummy::class);
|
||||
$definition->setArguments(array('$apiKey' => '123'));
|
||||
|
||||
$pass = new ResolveNamedArgumentsPass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testClassNotExist()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$definition = $container->register(NotExist::class, NotExist::class);
|
||||
$definition->setArguments(array('$apiKey' => '123'));
|
||||
|
||||
$pass = new ResolveNamedArgumentsPass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testClassNoConstructor()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$definition = $container->register(NoConstructor::class, NoConstructor::class);
|
||||
$definition->setArguments(array('$apiKey' => '123'));
|
||||
|
||||
$pass = new ResolveNamedArgumentsPass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testArgumentNotFound()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class);
|
||||
$definition->setArguments(array('$notFound' => '123'));
|
||||
|
||||
$pass = new ResolveNamedArgumentsPass();
|
||||
$pass->process($container);
|
||||
}
|
||||
}
|
||||
|
||||
class NoConstructor
|
||||
{
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class NamedArgumentsDummy
|
||||
{
|
||||
public function __construct(CaseSensitiveClass $c, $apiKey)
|
||||
{
|
||||
}
|
||||
|
||||
public function setApiKey($apiKey)
|
||||
{
|
||||
}
|
||||
}
|
@ -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 http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
<services>
|
||||
<service id="Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy">
|
||||
<argument />
|
||||
<argument key="$apiKey">ABCD</argument>
|
||||
<call method="setApiKey">
|
||||
<argument key="$apiKey">123</argument>
|
||||
</call>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
@ -0,0 +1,10 @@
|
||||
services:
|
||||
Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy: { 0: ~, $apiKey: ABCD }
|
||||
|
||||
another_one:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy
|
||||
arguments:
|
||||
0: ~
|
||||
$apiKey: ABCD
|
||||
calls:
|
||||
- ['setApiKey', { $apiKey: '123' }]
|
@ -25,6 +25,7 @@ use Symfony\Component\Config\Resource\DirectoryResource;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
@ -704,4 +705,18 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults_child')->getAutowiredCalls());
|
||||
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getAutowiredCalls());
|
||||
}
|
||||
|
||||
public function testNamedArguments()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
|
||||
$loader->load('services_named_args.xml');
|
||||
|
||||
$this->assertEquals(array(null, '$apiKey' => 'ABCD'), $container->getDefinition(NamedArgumentsDummy::class)->getArguments());
|
||||
|
||||
$container->compile();
|
||||
|
||||
$this->assertEquals(array(null, 'ABCD'), $container->getDefinition(NamedArgumentsDummy::class)->getArguments());
|
||||
$this->assertEquals(array(array('setApiKey', array('123'))), $container->getDefinition(NamedArgumentsDummy::class)->getMethodCalls());
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
@ -452,6 +453,22 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array('getbar' => array('bar' => new Reference('bar'))), $container->getDefinition('foo')->getOverriddenGetters());
|
||||
}
|
||||
|
||||
public function testNamedArguments()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
|
||||
$loader->load('services_named_args.yml');
|
||||
|
||||
$this->assertEquals(array(null, '$apiKey' => 'ABCD'), $container->getDefinition(NamedArgumentsDummy::class)->getArguments());
|
||||
$this->assertEquals(array(null, '$apiKey' => 'ABCD'), $container->getDefinition('another_one')->getArguments());
|
||||
|
||||
$container->compile();
|
||||
|
||||
$this->assertEquals(array(null, 'ABCD'), $container->getDefinition(NamedArgumentsDummy::class)->getArguments());
|
||||
$this->assertEquals(array(null, 'ABCD'), $container->getDefinition('another_one')->getArguments());
|
||||
$this->assertEquals(array(array('setApiKey', array('123'))), $container->getDefinition('another_one')->getMethodCalls());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The value of the "decorates" option for the "bar" service must be the id of the service without the "@" prefix (replace "@foo" with "foo").
|
||||
|
Reference in New Issue
Block a user