-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DI] Add exclude
to TaggedIterator
and TaggedLocator
#44774
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
Conversation
0a9ed22
to
19509c0
Compare
The fabbot.io suggestion doesn't make any sense. |
@nicolas-grekas Curious what you think about this approach. |
Hey! I think @fractalzombie has recently worked with this code. Maybe they can help review this? Cheers! Carsonbot |
@ruudk Hi, this is the first time I've seen such use of tags, I don't quite understand the rationality of this solution. |
This comment has been minimized.
This comment has been minimized.
Should it be added to this method too DependencyInjection/Loader/Configurator/ContainerConfigurator.php#L142 ? |
@Jeroeny Good one, added it to the to-do. First I would like to know if this is something that could be merged. Then I can improve/finalize the PR. |
Yes, you can ignore the suggestion. Fabbot tries really hard to act like a human, but sometimes they just can't hide being a robot :) |
exclude
option to TaggedIterator
attributeexclude
option to TaggedIterator
attribute
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.
Works for me, here are some notes. Thanks for submitting.
src/Symfony/Component/DependencyInjection/Argument/TaggedIteratorArgument.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Tests/Fixtures/AutoconfiguredInterface2.php
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Attribute/TaggedIterator.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
Outdated
Show resolved
Hide resolved
19509c0
to
3867821
Compare
exclude
option to TaggedIterator
attributeexclude
to TaggedIterator
and TaggedLocator
With this change, you can exclude one or more services from a tagged iterator or locator. It's common when working with Delegator or Chain services that call a list of services that implement an interface, to also want to implement the interface on Delegator/Chain. An example of this is in the Symfony HttpKernel component: https://github.com/symfony/symfony/blob/0d6e859db236e37b8baa2b2bf4c8b7d14d151570/src/Symfony/Component/HttpKernel/CacheClearer/CacheClearerInterface.php#L19-L25 https://github.com/symfony/symfony/blob/0d6e859db236e37b8baa2b2bf4c8b7d14d151570/src/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php#L21-L31 The `ChainCacheClearer` implements `CacheClearerInterface` and calls a list of `CacheClearerInterface` clearers. If that would have been configured with `#[AutoconfigureTag]` and `#[TaggedIterator]`, the `ChainCacheClearer` would receive itself in the `iterable $clearers`. With this change, it can exclude itself and rely fully on autowire/configure. Another example: ```php #[AutoconfigureTag] interface ErrorTracker { public function trackError(string $error): void; } final class SentryErrorTracker implement ErrorTracker { public function trackError(string $error): void { echo "Send error to Sentry\n"; } } final class NewRelicErrorTracker implement ErrorTracker { public function trackError(string $error): void { echo "Send error to NewRelic\n"; } } final class DelegatingErrorTracker implements ErrorTracker { public function __construct( #[TaggedIterator(ErrorTracker::class, exclude: self::class)] private iterable $trackers ) {} public function trackError(string $error): void { foreach($this->trackers as $tracker) { $tracker->trackError($error); } } } // Alias ErrorTracker interface to DelegatingErrorTracker service final class MyController { public function __construct(private ErrorTracker $errorTracker) {} public function __invoke() { $this->errorTracker->trackError('Hello, World!'); } } ``` Without this change, the `DelegatingErrorTracker` would receive itself in the tagged iterator.
3867821
to
c89fab7
Compare
@nicolas-grekas Thanks for your review, I applied your feedback and added more tests. The CI fails due to unrelated errors on |
exclude
to TaggedIterator
and TaggedLocator
exclude
to TaggedIterator
and TaggedLocator
Thank you @ruudk. |
exclude
to TaggedIterator
and TaggedLocator
exclude
to TaggedIterator
and TaggedLocator
…/locators exclude option to xml and yaml (HypeMC) This PR was merged into the 6.2 branch. Discussion ---------- [DependencyInjection] Add support for tagged iterators/locators exclude option to xml and yaml | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Followup to #44774 . The previous PR added support for the `exclude` option to php attributes & php config files, but not xml or yaml, making it impossible to use this feature with those config types. Also, since the support for this feature was never added to the yaml & xml dumpers, the generated `App_KernelDevDebugContainer.xml` is actually incorrect (possibly should be considered a bug), eg the following php configuration: ```php $services->set(TestExclude::class) ->public() ->args([ tagged_iterator('app.test', exclude: TestExclude::class), ]); ``` produces this xml file: ```xml <service id="App\Service\TestExclude" class="App\Service\TestExclude" public="true"> <tag name="app.test"/> <argument type="tagged_iterator" tag="app.test"/> </service> ``` With this PR, the dumpers are now aware of the `exclude` option: ```diff <service id="App\Service\TestExclude" class="App\Service\TestExclude" public="true"> <tag name="app.test"/> - <argument type="tagged_iterator" tag="app.test"/> + <argument type="tagged_iterator" tag="app.test" exclude="App\Service\TestExclude"/> </service> ``` Commits ------- 9afa5c9 [DI] Add support for tagged iterators/locators `exclude` option to xml and yaml
With this change, you can exclude one or more services from a tagged iterator
or locator.
It's common when working with Delegator or Chain services that call a list of services that
implement an interface, to also want to implement the interface on Delegator/Chain.
An example of this is in the Symfony HttpKernel component:
symfony/src/Symfony/Component/HttpKernel/CacheClearer/CacheClearerInterface.php
Lines 19 to 25 in 0d6e859
symfony/src/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php
Lines 21 to 31 in 0d6e859
The
ChainCacheClearer
implementsCacheClearerInterface
and calls a list ofCacheClearerInterface
clearers.
If that would have been configured with
#[AutoconfigureTag]
and#[TaggedIterator]
, theChainCacheClearer
would receive itself in theiterable $clearers
.With this change, it can exclude itself and rely fully on autowire/configure.
Another example:
Without this change, the
DelegatingErrorTracker
would receive itself in the taggediterator.