-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[Contracts][DependencyInjection] Add ServiceCollectionInterface
#53163
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
b801081 to
18cf8fe
Compare
src/Symfony/Component/DependencyInjection/ServiceCollectionInterface.php
Outdated
Show resolved
Hide resolved
18cf8fe to
6e48c4c
Compare
src/Symfony/Component/DependencyInjection/ServiceCollectionInterface.php
Outdated
Show resolved
Hide resolved
GromNaN
left a comment
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.
I commonly require a service locator which is also an iterator.
Could you provide examples where you need the service locator to be iterable. Maybe a link to the video with a point in time where "he could have benefited from this".
Here's a good example: https://github.com/symfony/ux/pull/1347/files#diff-6487ef7c39e106956904930b49958df26d90de6e025cd0c69a1a9a84e31ed064 (the entire class could be replaced with a |
6e48c4c to
ca47fd0
Compare
ServiceCollectionInterfaceServiceLocator iterable
|
Ok, I've removed the interface and just made |
ca47fd0 to
8db521a
Compare
|
| foreach (array_keys($this->getProvidedServices()) as $id) { | ||
| yield $id => $this->get($id); | ||
| } |
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.
This basically means that by iterating over the locator you initialize all of its services. To me, this kinda defeats the purpose of a service locator: I could've just injected a tagged iterator and called iterator_to_array() on it.
If we really want to make the locator traversable (not sure if we should yet), maybe we'd rather yield a service closure instead?
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.
but because this is a generator, this still does it kinda lazily so it's OK?
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.
I don't know, this still looks like a pitfall to me. I wouldn't do it.
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.
@kbond WDYT of this concern? I don't feel the need for this extra safety myself but maybe your experience could help best decide?
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.
I don't know, this still looks like a pitfall to me. I wouldn't do it.
Does the new interface alleviate the concern at all?
nicolas-grekas
left a comment
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.
The added method is just a helper: userland can do this iteration with any ServiceProviderInterface.
IoC principle would encourage using the interface.
Still worth it?
that's quite common needless overhead - we already simplified many components by using a container |
I guess you mean, inject a tagged iterator into the index action and the tagged locator into the show method? Indeed that would work.
This is true, and in fact what I've been doing, but in userland, What about a
I do still feel this improves the DX as the need for a service locator/iterator is a common pattern I'm seeing (but let's close if there isn't agreement). |
|
To make this full "IoC", one can type hint |
8db521a to
33d14d0
Compare
ServiceLocator iterableServiceCollectionInterface
ServiceCollectionInterfaceServiceCollectionInterface
|
As discussed with Nicolas on Slack, I've switched back to a |
nicolas-grekas
left a comment
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, thanks.
Please update the root composer.json for 3.5 also.
33d14d0 to
a47e84f
Compare
Done, but please confirm it's updated correctly. |
a47e84f to
578a99a
Compare
578a99a to
4a9e874
Compare
|
Thank you @kbond. |
…ctionInterface when declaring a service subscriber (nicolas-grekas) This PR was merged into the 7.2 branch. Discussion ---------- [DependencyInjection] Fix missing binding for ServiceCollectionInterface when declaring a service subscriber | Q | A | ------------- | --- | Branch? | 7.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | - | License | MIT Looks like we forgot this in #53163 I figured it out when reviewing symfony/symfony-docs#20961 Commits ------- 6174d09 [DependencyInjection] Fix missing binding for ServiceCollectionInterface when declaring a service subscriber
I commonly require a service locator which is also an iterator. I noticed during @weaverryan's most recent livestream he could have benefited from this as well. There are currently three ways to achieve:
ServiceLocatorand useServiceLocator::getProvidedServices()in the decorator'sgetIterator()ContainerInterface::get()method which iterates over all items until it finds a match (this is what Ryan did in his livestream)This PR proposes a new
ServiceCollectionInterfacewhich is a countable, iterable,ContainerInterface.I'm implemented on the current
ServiceLocatorso any place this is used in your code, you can now type-hintServiceCollectionInterface: