[DependencyInjection] Allow binding iterable and tagged services

This commit is contained in:
Grégoire Pineau 2019-09-18 11:21:30 +02:00
parent 1efae63e64
commit 2055a558fe
4 changed files with 11 additions and 5 deletions

View File

@ -9,6 +9,7 @@ CHANGELOG
* deprecated support for short factories and short configurators in Yaml * deprecated support for short factories and short configurators in Yaml
* deprecated `tagged` in favor of `tagged_iterator` * deprecated `tagged` in favor of `tagged_iterator`
* deprecated passing an instance of `Symfony\Component\DependencyInjection\Parameter` as class name to `Symfony\Component\DependencyInjection\Definition` * deprecated passing an instance of `Symfony\Component\DependencyInjection\Parameter` as class name to `Symfony\Component\DependencyInjection\Definition`
* added support for binding iterable and tagged services
4.3.0 4.3.0
----- -----

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Compiler; namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Argument\BoundArgument; use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
@ -120,8 +121,8 @@ class ResolveBindingsPass extends AbstractRecursivePass
continue; continue;
} }
if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition) { if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition && !$bindingValue instanceof TaggedIteratorArgument) {
throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected null, an instance of %s or an instance of %s, %s given.', $key, $this->currentId, Reference::class, Definition::class, \gettype($bindingValue))); throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected null, an instance of %s or an instance of %s or an instance of %s, %s given.', $key, $this->currentId, Reference::class, Definition::class, TaggedIteratorArgument::class, \gettype($bindingValue)));
} }
} }

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Argument\BoundArgument; use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass; use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass;
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass; use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -31,7 +32,10 @@ class ResolveBindingsPassTest extends TestCase
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$bindings = [CaseSensitiveClass::class => new BoundArgument(new Reference('foo'))]; $bindings = [
CaseSensitiveClass::class => new BoundArgument(new Reference('foo')),
'iterable $objects' => new BoundArgument(new TaggedIteratorArgument('tag.name'), true, BoundArgument::INSTANCEOF_BINDING),
];
$definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class);
$definition->setArguments([1 => '123']); $definition->setArguments([1 => '123']);
@ -44,7 +48,7 @@ class ResolveBindingsPassTest extends TestCase
$pass = new ResolveBindingsPass(); $pass = new ResolveBindingsPass();
$pass->process($container); $pass->process($container);
$this->assertEquals([new Reference('foo'), '123'], $definition->getArguments()); $this->assertEquals([0 => new Reference('foo'), 1 => '123', 4 => new TaggedIteratorArgument('tag.name')], $definition->getArguments());
$this->assertEquals([['setSensitiveClass', [new Reference('foo')]]], $definition->getMethodCalls()); $this->assertEquals([['setSensitiveClass', [new Reference('foo')]]], $definition->getMethodCalls());
} }

View File

@ -9,7 +9,7 @@ use Psr\Container\ContainerInterface;
*/ */
class NamedArgumentsDummy class NamedArgumentsDummy
{ {
public function __construct(CaseSensitiveClass $c, $apiKey, $hostName, ContainerInterface $interface) public function __construct(CaseSensitiveClass $c, $apiKey, $hostName, ContainerInterface $interface, iterable $objects)
{ {
} }