Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bef46c8

Browse files
feature #49433 [DependencyInjection] allow extending Autowire attribute (kbond)
This PR was merged into the 6.3 branch. Discussion ---------- [DependencyInjection] allow extending `Autowire` attribute | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | n/a | License | MIT | Doc PR | todo This allows 3rd party package developers to make custom `Autowire` attribute helpers. Example: ```php class Repository extends Autowire { public function __construct(string $class) { parent::__construct(expression: \sprintf("service('some.repository.factory').create('%s')", $class)); } } ``` And then it could be used with: ```php /** * `@param` ObjectRepository<User> $repository */ public function __construct(#[Repository(User::class)] private ObjectRepository $repository) { } ``` Commits ------- c463133 [DI] allow extending `Autowire` attribute
2 parents 798efba + c463133 commit bef46c8

File tree

7 files changed

+34
-7
lines changed

7 files changed

+34
-7
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CHANGELOG
1313
* Enable deprecating parameters with `ContainerBuilder::deprecateParameter()`
1414
* Add `#[AsAlias]` attribute to tell under which alias a service should be registered or to use the implemented interface if no parameter is given
1515
* Allow to trim XML service parameters value by using `trim="true"` attribute
16+
* Allow extending the `Autowire` attribute
1617

1718
6.2
1819
---

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,11 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
292292
}
293293

294294
if ($checkAttributes) {
295-
foreach ($parameter->getAttributes() as $attribute) {
296-
if (\in_array($attribute->getName(), [TaggedIterator::class, TaggedLocator::class, Autowire::class, MapDecorated::class], true)) {
295+
foreach ([TaggedIterator::class, TaggedLocator::class, Autowire::class, MapDecorated::class] as $attributeClass) {
296+
foreach ($parameter->getAttributes($attributeClass, Autowire::class === $attributeClass ? \ReflectionAttribute::IS_INSTANCEOF : 0) as $attribute) {
297297
$arguments[$index] = $this->processAttribute($attribute->newInstance(), $parameter->allowsNull());
298298

299-
continue 2;
299+
continue 3;
300300
}
301301
}
302302
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ public function testAutowireAttribute()
12351235

12361236
$definition = $container->getDefinition(AutowireAttribute::class);
12371237

1238-
$this->assertCount(9, $definition->getArguments());
1238+
$this->assertCount(10, $definition->getArguments());
12391239
$this->assertEquals(new Reference('some.id'), $definition->getArgument(0));
12401240
$this->assertEquals(new Expression("parameter('some.parameter')"), $definition->getArgument(1));
12411241
$this->assertSame('foo/bar', $definition->getArgument(2));
@@ -1244,7 +1244,8 @@ public function testAutowireAttribute()
12441244
$this->assertEquals(new Expression("parameter('some.parameter')"), $definition->getArgument(5));
12451245
$this->assertSame('bar', $definition->getArgument(6));
12461246
$this->assertSame('@bar', $definition->getArgument(7));
1247-
$this->assertEquals(new Reference('invalid.id', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(8));
1247+
$this->assertSame('foo', $definition->getArgument(8));
1248+
$this->assertEquals(new Reference('invalid.id', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(9));
12481249

12491250
$container->compile();
12501251

@@ -1257,6 +1258,7 @@ public function testAutowireAttribute()
12571258
$this->assertSame('foo', $service->expressionAsValue);
12581259
$this->assertSame('bar', $service->rawValue);
12591260
$this->assertSame('@bar', $service->escapedRawValue);
1261+
$this->assertSame('foo', $service->customAutowire);
12601262
$this->assertNull($service->invalid);
12611263
}
12621264

src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes_80.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ class AutowireProperty
3333
public Foo $foo;
3434
}
3535

36+
#[\Attribute(\Attribute::TARGET_PARAMETER)]
37+
class CustomAutowire extends Autowire
38+
{
39+
public function __construct(string $parameter)
40+
{
41+
parent::__construct(param: $parameter);
42+
}
43+
}
44+
3645
class AutowireAttribute
3746
{
3847
public function __construct(
@@ -52,6 +61,8 @@ public function __construct(
5261
public string $rawValue,
5362
#[Autowire('@@bar')]
5463
public string $escapedRawValue,
64+
#[CustomAutowire('some.parameter')]
65+
public string $customAutowire,
5566
#[Autowire(service: 'invalid.id')]
5667
public ?\stdClass $invalid = null,
5768
) {

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* Add `#[WithHttpStatus]` for defining status codes for exceptions
1010
* Use an instance of `Psr\Clock\ClockInterface` to generate the current date time in `DateTimeValueResolver`
1111
* Add `#[WithLogLevel]` for defining log levels for exceptions
12+
* Allow extending the `Autowire` attribute
1213

1314
6.2
1415
---

src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public function process(ContainerBuilder $container)
146146
$args[$p->name] = $bindingValue;
147147

148148
continue;
149-
} elseif (!$autowire || (!($autowireAttributes ??= $p->getAttributes(Autowire::class)) && (!$type || '\\' !== $target[0]))) {
149+
} elseif (!$autowire || (!($autowireAttributes ??= $p->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)) && (!$type || '\\' !== $target[0]))) {
150150
continue;
151151
} elseif (is_subclass_of($type, \UnitEnum::class)) {
152152
// do not attempt to register enum typed arguments if not already present in bindings

src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,14 +482,15 @@ public function testAutowireAttribute()
482482

483483
$locator = $container->get($locatorId)->get('foo::fooAction');
484484

485-
$this->assertCount(7, $locator->getProvidedServices());
485+
$this->assertCount(8, $locator->getProvidedServices());
486486
$this->assertInstanceOf(\stdClass::class, $locator->get('service1'));
487487
$this->assertSame('foo/bar', $locator->get('value'));
488488
$this->assertSame('foo', $locator->get('expression'));
489489
$this->assertInstanceOf(\stdClass::class, $locator->get('serviceAsValue'));
490490
$this->assertInstanceOf(\stdClass::class, $locator->get('expressionAsValue'));
491491
$this->assertSame('bar', $locator->get('rawValue'));
492492
$this->assertSame('@bar', $locator->get('escapedRawValue'));
493+
$this->assertSame('foo', $locator->get('customAutowire'));
493494
$this->assertFalse($locator->has('service2'));
494495
}
495496
}
@@ -580,6 +581,15 @@ public function fooAction(Response $response, ?Response $nullableResponse)
580581
}
581582
}
582583

584+
#[\Attribute(\Attribute::TARGET_PARAMETER)]
585+
class CustomAutowire extends Autowire
586+
{
587+
public function __construct(string $parameter)
588+
{
589+
parent::__construct(param: $parameter);
590+
}
591+
}
592+
583593
class WithAutowireAttribute
584594
{
585595
public function fooAction(
@@ -597,6 +607,8 @@ public function fooAction(
597607
string $rawValue,
598608
#[Autowire('@@bar')]
599609
string $escapedRawValue,
610+
#[CustomAutowire('some.parameter')]
611+
string $customAutowire,
600612
#[Autowire(service: 'invalid.id')]
601613
\stdClass $service2 = null,
602614
) {

0 commit comments

Comments
 (0)