-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[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
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
ServiceCollectionInterface
ServiceLocator
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?
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
ServiceCollectionInterface
ServiceCollectionInterface
As discussed with Nicolas on Slack, I've switched back to a |
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. |
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:
ServiceLocator
and 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
ServiceCollectionInterface
which is a countable, iterable,ContainerInterface
.I'm implemented on the current
ServiceLocator
so any place this is used in your code, you can now type-hintServiceCollectionInterface
: