Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7abe927

Browse filesBrowse files
committed
[DependencyInjection] Add support for excluding services with declared custom attribute
1 parent 4813d66 commit 7abe927
Copy full SHA for 7abe927

File tree

6 files changed

+80
-3
lines changed
Filter options

6 files changed

+80
-3
lines changed

‎src/Symfony/Component/DependencyInjection/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.4
5+
---
6+
7+
* Add support for excluding services with declared custom attribute (`ContainerBuilder::registerAttributeForExclusion`)
8+
49
6.3
510
---
611

‎src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
131131
*/
132132
private array $autoconfiguredAttributes = [];
133133

134+
/**
135+
* @var array<class-string>
136+
*/
137+
private array $exclusionAttributes = [];
138+
134139
/**
135140
* @var array<string, bool>
136141
*/
@@ -1372,6 +1377,20 @@ public function registerAttributeForAutoconfiguration(string $attributeClass, ca
13721377
$this->autoconfiguredAttributes[$attributeClass] = $configurator;
13731378
}
13741379

1380+
/**
1381+
* Registers an attribute that will be used for excluding all services from classes it is declared on.
1382+
*
1383+
* @param class-string $attributeClass
1384+
*/
1385+
public function registerAttributeForExclusion(string $attributeClass): void
1386+
{
1387+
if (in_array($attributeClass, $this->exclusionAttributes)) {
1388+
return;
1389+
}
1390+
1391+
$this->exclusionAttributes[] = $attributeClass;
1392+
}
1393+
13751394
/**
13761395
* Registers an autowiring alias that only binds to a specific argument name.
13771396
*
@@ -1409,6 +1428,14 @@ public function getAutoconfiguredAttributes(): array
14091428
return $this->autoconfiguredAttributes;
14101429
}
14111430

1431+
/**
1432+
* @return array<class-string>
1433+
*/
1434+
public function getExclusionAttributes(): array
1435+
{
1436+
return $this->exclusionAttributes;
1437+
}
1438+
14121439
/**
14131440
* Resolves env parameter placeholders in a string or an array.
14141441
*

‎src/Symfony/Component/DependencyInjection/Loader/FileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/FileLoader.php
+9-3Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,17 @@ public function registerClasses(Definition $prototype, string $namespace, string
124124

125125
foreach ($classes as $class => $errorMessage) {
126126
if (null === $errorMessage && $autoconfigureAttributes) {
127+
$exclusionAttributes = $this->container->getExclusionAttributes();
128+
$exclusionAttributes[] = Exclude::class;
129+
127130
$r = $this->container->getReflectionClass($class);
128-
if ($r->getAttributes(Exclude::class)[0] ?? null) {
129-
$this->addContainerExcludedTag($class, $source);
130-
continue;
131+
foreach ($exclusionAttributes as $attribute) {
132+
if ($r->getAttributes($attribute)[0] ?? null) {
133+
$this->addContainerExcludedTag($class, $source);
134+
continue 2;
135+
}
131136
}
137+
132138
if ($this->env) {
133139
$attribute = null;
134140
foreach ($r->getAttributes(When::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Utils;
4+
5+
#[ToBeExcluded]
6+
class ServiceWithAttributeForExclusion
7+
{
8+
}
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Utils;
4+
5+
#[\Attribute(\Attribute::TARGET_CLASS)]
6+
class ToBeExcluded
7+
{
8+
}

‎src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
use Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\WithAsAliasInterface;
4242
use Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\WithAsAliasMultiple;
4343
use Symfony\Component\DependencyInjection\Tests\Fixtures\Utils\NotAService;
44+
use Symfony\Component\DependencyInjection\Tests\Fixtures\Utils\ServiceWithAttributeForExclusion;
45+
use Symfony\Component\DependencyInjection\Tests\Fixtures\Utils\ToBeExcluded;
4446

4547
class FileLoaderTest extends TestCase
4648
{
@@ -164,6 +166,27 @@ public function testRegisterClassesWithExcludeAttribute(bool $autoconfigure)
164166
$this->assertSame($autoconfigure, $container->getDefinition(NotAService::class)->hasTag('container.excluded'));
165167
}
166168

169+
/**
170+
* @testWith [true]
171+
* [false]
172+
*/
173+
public function testRegisterClassesWithAttributeMarkedForExclusion(bool $autoconfigure)
174+
{
175+
$container = new ContainerBuilder();
176+
177+
$container->registerAttributeForExclusion(ToBeExcluded::class);
178+
179+
$loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
180+
181+
$loader->registerClasses(
182+
(new Definition())->setAutoconfigured($autoconfigure),
183+
'Symfony\Component\DependencyInjection\Tests\Fixtures\Utils\\',
184+
'Utils/*',
185+
);
186+
187+
$this->assertSame($autoconfigure, $container->getDefinition(ServiceWithAttributeForExclusion::class)->hasTag('container.excluded'));
188+
}
189+
167190
public function testRegisterClassesWithExcludeAsArray()
168191
{
169192
$container = new ContainerBuilder();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.