Skip to content

Commit 57f4b25

Browse files
committed
[DependencyInjection] #[Autowire] attribute should have precedence over bindings
1 parent 37d0e25 commit 57f4b25

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
1515
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1616
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
17+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
1718
use Symfony\Component\DependencyInjection\Attribute\Target;
1819
use Symfony\Component\DependencyInjection\ContainerBuilder;
1920
use Symfony\Component\DependencyInjection\Definition;
@@ -185,6 +186,9 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
185186
if (\array_key_exists($parameter->name, $arguments) && '' !== $arguments[$parameter->name]) {
186187
continue;
187188
}
189+
if ($parameter->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)) {
190+
continue;
191+
}
188192

189193
$typeHint = ltrim(ProxyHelper::exportType($parameter) ?? '', '?');
190194

src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithDefaultIndexMethodAndWithDefaultPriorityMethod;
4848
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithDefaultPriorityMethod;
4949
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithoutIndex;
50+
use Symfony\Component\DependencyInjection\Tests\Fixtures\LocatorConsumerWithServiceSubscriber;
5051
use Symfony\Component\DependencyInjection\Tests\Fixtures\StaticMethodTag;
5152
use Symfony\Component\DependencyInjection\Tests\Fixtures\TaggedConsumerWithExclude;
5253
use Symfony\Component\DependencyInjection\Tests\Fixtures\TaggedService1;
@@ -1085,6 +1086,34 @@ public function testTaggedIteratorAndLocatorWithExclude()
10851086
$this->assertTrue($locator->has(AutoconfiguredService2::class));
10861087
$this->assertFalse($locator->has(TaggedConsumerWithExclude::class));
10871088
}
1089+
1090+
public function testAutowireAttributeHasPriorityOverBindings()
1091+
{
1092+
$container = new ContainerBuilder();
1093+
$container->register(FooTagClass::class)
1094+
->setPublic(true)
1095+
->addTag('foo_bar', ['key' => 'tagged_service'])
1096+
;
1097+
$container->register(LocatorConsumerWithServiceSubscriber::class)
1098+
->setPublic(true)
1099+
->setAutowired(true)
1100+
->addTag('container.service_subscriber')
1101+
;
1102+
$container->register('subscribed_service', \stdClass::class)
1103+
->setPublic(true)
1104+
;
1105+
1106+
$container->compile();
1107+
1108+
/** @var LocatorConsumerWithServiceSubscriber $s */
1109+
$s = $container->get(LocatorConsumerWithServiceSubscriber::class);
1110+
1111+
self::assertInstanceOf(ContainerInterface::class, $subscriberLocator = $s->getContainer());
1112+
self::assertTrue($subscriberLocator->has('subscribed_service'));
1113+
self::assertNotSame($subscriberLocator, $taggedLocator = $s->getLocator());
1114+
self::assertInstanceOf(ContainerInterface::class, $taggedLocator);
1115+
self::assertTrue($taggedLocator->has('tagged_service'));
1116+
}
10881117
}
10891118

10901119
class ServiceSubscriberStub implements ServiceSubscriberInterface
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
16+
use Symfony\Contracts\Service\Attribute\Required;
17+
use Symfony\Contracts\Service\ServiceSubscriberInterface;
18+
19+
final class LocatorConsumerWithServiceSubscriber implements ServiceSubscriberInterface
20+
{
21+
private ?ContainerInterface $container = null;
22+
23+
public function __construct(
24+
#[TaggedLocator('foo_bar', indexAttribute: 'key')]
25+
private ContainerInterface $locator,
26+
) {
27+
}
28+
29+
public function getLocator(): ContainerInterface
30+
{
31+
return $this->locator;
32+
}
33+
34+
public function getContainer(): ?ContainerInterface
35+
{
36+
return $this->container;
37+
}
38+
39+
#[Required]
40+
public function setContainer(ContainerInterface $container): void
41+
{
42+
$this->container = $container;
43+
}
44+
45+
public static function getSubscribedServices(): array
46+
{
47+
return [
48+
'subscribed_service',
49+
];
50+
}
51+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy