8000 [DependencyInjection] Add `#[AutowireIterator]` attribute and improve `#[AutowireLocator]` by nicolas-grekas · Pull Request #51832 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[DependencyInjection] Add #[AutowireIterator] attribute and improve #[AutowireLocator] #51832

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
[DependencyInjection] Add tests for AutowireLocator/AutowireIterator
  • Loading branch information
kbond authored and nicolas-grekas committed Oct 6, 2023
commit a87f2e0c248e5e22c9445ba2f371ab667e49faf8
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Psr\Container\ContainerInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
Expand All @@ -32,6 +33,7 @@
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfiguredInterface2;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfiguredService1;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfiguredService2;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutowireIteratorConsumer;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutowireLocatorConsumer;
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarTagClass;
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooBarTaggedClass;
Expand Down Expand Up @@ -392,6 +394,7 @@ public function testTaggedServiceWithIndexAttributeAndDefaultMethod()
public function testLocatorConfiguredViaAttribute()
{
$container = new ContainerBuilder();
$container->setParameter('some.parameter', 'foo');
$container->register(BarTagClass::class)
->setPublic(true)
;
Expand All @@ -411,6 +414,36 @@ public function testLocatorConfiguredViaAttribute()
self::assertSame($container->get(BarTagClass::class), $s->locator->get(BarTagClass::class));
self::assertSame($container->get(FooTagClass::class), $s->locator->get('with_key'));
self::assertFalse($s->locator->has('nullable'));
self::assertSame('foo', $s->locator->get('subscribed'));
}

public function testIteratorConfiguredViaAttribute()
{
$container = new ContainerBuilder();
$container->setParameter('some.parameter', 'foo');
$container->register(BarTagClass::class)
->setPublic(true)
;
$container->register(FooTagClass::class)
->setPublic(true)
;
$container->register(AutowireIteratorConsumer::class)
->setAutowired(true)
->setPublic(true)
;

$container->compile();

/** @var AutowireIteratorConsumer $s */
$s = $container->get(AutowireIteratorConsumer::class);

self::assertInstanceOf(RewindableGenerator::class, $s->iterator);

$values = iterator_to_array($s->iterator);
self::assertCount(3, $values);
self::assertSame($container->get(BarTagClass::class), $values[BarTagClass::class]);
self::assertSame($container->get(FooTagClass::class), $values['with_key']);
self::assertSame('foo', $values['subscribed']);
}

public function testTaggedServiceWithIndexAttributeAndDefaultMethodConfiguredViaAttribute()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?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\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
use Symfony\Contracts\Service\Attribute\SubscribedService;

final class AutowireIteratorConsumer
{
public function __construct(
#[AutowireIterator([
BarTagClass::class,
'with_key' => FooTagClass::class,
'nullable' => '?invalid',
'subscribed' => new SubscribedService(type: 'string', attributes: new Autowire('%some.parameter%')),
])]
public readonly iterable $iterator,
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Contracts\Service\Attribute\SubscribedService;

final class AutowireLocatorConsumer
{
Expand All @@ -21,6 +23,7 @@ public function __construct(
BarTagClass::class,
'with_key' => FooTagClass::class,
'nullable' => '?invalid',
'subscribed' => new SubscribedService(type: 'string', attributes: new Autowire('%some.parameter%')),
])]
public readonly ContainerInterface $locator,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;

final class TaggedIteratorConsumer
{
public function __construct(
#[TaggedIterator('foo_bar', indexAttribute: 'foo')]
#[AutowireIterator('foo_bar', indexAttribute: 'foo')]
private iterable $param,
) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;

final class TaggedLocatorConsumer
{
public function __construct(
#[TaggedLocator('foo_bar', indexAttribute: 'foo')]
#[AutowireLocator('foo_bar', indexAttribute: 'foo')]
private ContainerInterface $locator,
) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DependencyInjection\Attribute\AutowireCallable;
use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
9E88 Expand All @@ -31,6 +32,7 @@
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DependencyInjection\RegisterControllerArgumentLocatorsPass;
use Symfony\Component\HttpKernel\Tests\Fixtures\Suit;
use Symfony\Contracts\Service\Attribute\SubscribedService;

class RegisterControllerArgumentLocatorsPassTest extends TestCase
{
Expand Down Expand Up @@ -499,6 +501,7 @@ public function testAutowireAttribute()
public function testTaggedIteratorAndTaggedLocatorAttributes()
{
$container = new ContainerBuilder();
$container->setParameter('some.parameter', 'bar');
$resolver = $container->register('argument_resolver.service', \stdClass::class)->addArgument([]);

$container->register('bar', \stdClass::class)->addTag('foobar');
Expand All @@ -517,25 +520,48 @@ public function testTaggedIteratorAndTaggedLocatorAttributes()
/** @var ServiceLocator $locator */
$locator = $container->get($locatorId)->get('foo::fooAction');

$this->assertCount(3, $locator->getProvidedServices());
$this->assertCount(7, $locator->getProvidedServices());

$this->assertTrue($locator->has('iterator'));
$this->assertInstanceOf(RewindableGenerator::class, $argIterator = $locator->get('iterator'));
$this->assertTrue($locator->has('iterator1'));
$this->assertInstanceOf(RewindableGenerator::class, $argIterator = $locator->get('iterator1'));
$this->assertCount(2, $argIterator);

$this->assertTrue($locator->has('locator'));
$this->assertInstanceOf(ServiceLocator::class, $argLocator = $locator->get('locator'));
$this->assertTrue($locator->has('iterator2'));
$this->assertInstanceOf(RewindableGenerator::class, $argIterator = $locator->get('iterator2'));
$this->assertCount(2, $argIterator);

$this->assertTrue($locator->has('locator1'));
$this->assertInstanceOf(ServiceLocator::class, $argLocator = $locator->get('locator1'));
$this->assertCount(2, $argLocator);
$this->assertTrue($argLocator->has('bar'));
$this->assertTrue($argLocator->has('baz'));

$this->assertSame(iterator_to_array($argIterator), [$argLocator->get('bar'), $argLocator->get('baz')]);

$this->assertTrue($locator->has('locator2'));
$this->assertInstanceOf(ServiceLocator::class, $argLocator = $locator->get('locator2'));
$this->assertCount(2, $argLocator);
$this->assertTrue($argLocator->has('bar'));
$this->assertTrue($argLocator->has('baz'));

$this->assertSame(iterator_to_array($argIterator), [$argLocator->get('bar'), $argLocator->get('baz')]);

$this->assertTrue($locator->has('container'));
$this->assertInstanceOf(ServiceLocator::class, $argLocator = $locator->get('container'));
$this->assertTrue($locator->has('container1'));
$this->assertInstanceOf(ServiceLocator::class, $argLocator = F438 $locator->get('container1'));
$this->assertCount(2, $argLocator);
$this->assertTrue($argLocator->has('bar'));
$this->assertTrue($argLocator->has('baz'));

$this->assertTrue($locator->has('container2'));
$this->assertInstanceOf(ServiceLocator::class, $argLocator = $locator->get('container2'));
$this->assertCount(1, $argLocator);
$this->assertTrue($argLocator->has('foo'));
$this->assertSame('bar', $argLocator->get('foo'));

$this->assertTrue($locator->has('iterator3'));
$this->assertInstanceOf(RewindableGenerator::class, $argIterator = $locator->get('iterator3'));
$this->assertCount(1, $argIterator);
$this->assertSame('bar', iterator_to_array($argIterator)['foo']);
}
}

Expand Down Expand Up @@ -674,9 +700,13 @@ public function fooAction(
class WithTaggedIteratorAndTaggedLocator
{
public function fooAction(
#[TaggedIterator('foobar')] iterable $iterator,
#[TaggedLocator('foobar')] ServiceLocator $locator,
#[AutowireLocator(['bar', 'baz'])] ContainerInterface $container,
#[TaggedIterator('foobar')] iterable $iterator1,
#[AutowireIterator('foobar')] iterable $iterator2,
#[TaggedLocator('foobar')] ServiceLocator $locator1,
#[AutowireLocator('foobar')] ServiceLocator $locator2,
#[AutowireLocator(['bar', 'baz'])] ContainerInterface $container1,
#[AutowireLocator(['foo' => new SubscribedService(type: 'string', attributes: new Autowire('%some.parameter%'))])] ContainerInterface $container2,
#[AutowireIterator(['foo' => new SubscribedService(type: 'string', attributes: new Autowire('%some.parameter%'))])] iterable $iterator3,
) {
}
}
1 change: 1 addition & 0 deletions src/Symfony/Component/HttpKernel/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"symfony/http-client-contracts": "<2.5",
"symfony/mailer": "<5.4",
"symfony/messenger": "<5.4",
"symfony/service-contracts": "<3.2",
Copy link
Contributor
@bendavies bendavies Oct 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kbond why was this added? is there a way to remove this conflict?

this makes it not possible for us to upgrade to symfony 6.4 because this forces a requirement for psr/container ^2.0, and we are still on v1 because the latest version of laminas/laminas-servicemanager requires v1:
https://github.com/laminas/laminas-servicemanager/blob/3.23.x/composer.json#L26

this is sort of the same issue as api-platform/core#5811

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @kbond, tagged you as it looked like your commit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed because the test case uses the $type argument of SubscribedService, which exists since 3.2.
PR welcome to change the test case and relax this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

"symfony/translation": "<5.4",
"symfony/translation-contracts": "<2.5",
"symfony/twig-bridge": "<5.4",
Expand Down
0