Skip to content

Commit cd64c67

Browse files
lyrixxnicolas-grekas
authored andcommitted
[DependencyInjection] Add support for Exclude attribute
1 parent fa37492 commit cd64c67

File tree

5 files changed

+67
-9
lines changed

5 files changed

+67
-9
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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\Attribute;
13+
14+
/**
15+
* An attribute to tell the class should not be registered as service.
16+
*
17+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
18+
*/
19+
#[\Attribute(\Attribute::TARGET_CLASS)]
20+
class Exclude
21+
{
22+
}

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ CHANGELOG
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
1616
* Allow extending the `Autowire` attribute
17+
* Add `#[Exclude]` to skip autoregistering a class
1718

1819
6.2
1920
---

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Config\Resource\GlobResource;
2020
use Symfony\Component\DependencyInjection\Alias;
2121
use Symfony\Component\DependencyInjection\Attribute\AsAlias;
22+
use Symfony\Component\DependencyInjection\Attribute\Exclude;
2223
use Symfony\Component\DependencyInjection\Attribute\When;
2324
use Symfony\Component\DependencyInjection\ChildDefinition;
2425
use Symfony\Component\DependencyInjection\Compiler\RegisterAutoconfigureAttributesPass;
@@ -122,18 +123,23 @@ public function registerClasses(Definition $prototype, string $namespace, string
122123
$serializedPrototype = serialize($prototype);
123124

124125
foreach ($classes as $class => $errorMessage) {
125-
if (null === $errorMessage && $autoconfigureAttributes && $this->env) {
126+
if (null === $errorMessage && $autoconfigureAttributes) {
126127
$r = $this->container->getReflectionClass($class);
127-
$attribute = null;
128-
foreach ($r->getAttributes(When::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
129-
if ($this->env === $attribute->newInstance()->env) {
130-
$attribute = null;
131-
break;
132-
}
133-
}
134-
if (null !== $attribute) {
128+
if ($r->getAttributes(Exclude::class)[0] ?? null) {
135129
continue;
136130
}
131+
if ($this->env) {
132+
$attribute = null;
133+
foreach ($r->getAttributes(When::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
134+
if ($this->env === $attribute->newInstance()->env) {
135+
$attribute = null;
136+
break;
137+
}
138+
}
139+
if (null !== $attribute) {
140+
continue;
141+
}
142+
}
137143
}
138144

139145
if (interface_exists($class, false)) {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Utils;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\Exclude;
6+
7+
#[Exclude]
8+
class NotAService
9+
{
10+
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
use Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\WithAsAliasIdMultipleInterface;
4141
use Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\WithAsAliasInterface;
4242
use Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\WithAsAliasMultiple;
43+
use Symfony\Component\DependencyInjection\Tests\Fixtures\Utils\NotAService;
4344

4445
class FileLoaderTest extends TestCase
4546
{
@@ -145,6 +146,24 @@ public function testRegisterClassesWithExclude()
145146
);
146147
}
147148

149+
/**
150+
* @testWith [true]
151+
* [false]
152+
*/
153+
public function testRegisterClassesWithExcludeAttribute(bool $autoconfigure)
154+
{
155+
$container = new ContainerBuilder();
156+
$loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
157+
158+
$loader->registerClasses(
159+
(new Definition())->setAutoconfigured($autoconfigure),
160+
'Symfony\Component\DependencyInjection\Tests\Fixtures\Utils\\',
161+
'Utils/*',
162+
);
163+
164+
$this->assertSame(!$autoconfigure, $container->hasDefinition(NotAService::class));
165+
}
166+
148167
public function testRegisterClassesWithExcludeAsArray()
149168
{
150169
$container = new ContainerBuilder();

0 commit comments

Comments
 (0)