-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DependencyInjection] Add support for excluding services with declared custom attribute #50447
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
base: 7.4
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -27,6 +27,7 @@ | |||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; | ||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocator; | ||||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; | ||||||
use Symfony\Component\DependencyInjection\Attribute\Exclude; | ||||||
use Symfony\Component\DependencyInjection\Attribute\Target; | ||||||
use Symfony\Component\DependencyInjection\Compiler\Compiler; | ||||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||||||
|
@@ -131,6 +132,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface | |||||
*/ | ||||||
private array $autoconfiguredAttributes = []; | ||||||
|
||||||
/** | ||||||
* @var array<class-string> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?
Suggested change
|
||||||
*/ | ||||||
private array $exclusionAttributes = [Exclude::class]; | ||||||
|
||||||
/** | ||||||
* @var array<string, bool> | ||||||
*/ | ||||||
|
@@ -1341,6 +1347,20 @@ public function registerAttributeForAutoconfiguration(string $attributeClass, ca | |||||
$this->autoconfiguredAttributes[$attributeClass] = $configurator; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Registers an attribute that will be used for excluding all services from classes it is declared on. | ||||||
* | ||||||
* @param class-string $attributeClass | ||||||
*/ | ||||||
public function registerAttributeForExclusion(string $attributeClass): void | ||||||
{ | ||||||
if (\in_array($attributeClass, $this->exclusionAttributes)) { | ||||||
return; | ||||||
} | ||||||
|
||||||
$this->exclusionAttributes[] = $attributeClass; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Registers an autowiring alias that only binds to a specific argument name. | ||||||
* | ||||||
|
@@ -1386,6 +1406,14 @@ public function getAutoconfiguredAttributes(): array | |||||
return $this->autoconfiguredAttributes; | ||||||
} | ||||||
|
||||||
/** | ||||||
* @return array<class-string> | ||||||
*/ | ||||||
public function getExclusionAttributes(): array | ||||||
{ | ||||||
return $this->exclusionAttributes; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Resolves env parameter placeholders in a string or an array. | ||||||
* | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,10 +140,15 @@ public function registerClasses(Definition $prototype, string $namespace, string | |
foreach ($classes as $class => $errorMessage) { | ||
if (null === $errorMessage && $autoconfigureAttributes) { | ||
$r = $this->container->getReflectionClass($class); | ||
if ($r->getAttributes(Exclude::class)[0] ?? null) { | ||
$this->addContainerExcludedTag($class, $source); | ||
continue; | ||
$exclusionAttributes = $this->container->getExclusionAttributes(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC, file loaders are run on separate container instances, right? This would mean that a bundle cannot expect registerAttributeForExclusion to have any effect on classes in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about this? did you give it a try? configuring an exclusion within a bundle and seeing it work on the app? |
||
|
||
foreach ($exclusionAttributes as $attribute) { | ||
if ($r->getAttributes($attribute)[0] ?? null) { | ||
$this->addContainerExcludedTag($class, $source); | ||
continue 2; | ||
} | ||
} | ||
|
||
if ($this->env) { | ||
$attribute = null; | ||
foreach ($r->getAttributes(When::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Utils; | ||
|
||
#[ToBeExcluded] | ||
class ServiceWithAttributeForExclusion | ||
{ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Utils; | ||
|
||
#[\Attribute(\Attribute::TARGET_CLASS)] | ||
class ToBeExcluded | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be great to allow this feature to work even if the attribute class doesn't not exist. |
||
{ | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.