-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[RFC] Simplify wiring of service locators #29203
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
Comments
Sorry but your description is not understandable to me. What kind of feedback are you asking for in this RFC? |
@Tobion You are right, I just re-read it and it does sound confusing. I wanted to explain how this site works and why it is so fast; I did it because @nicolas-grekas was interested in that and I don't have a blog. So I am closing it and when I make this as a bundle, I might create new RFC with link only. However I think the idea of autowired service locators (for tagged services) is still something very usable and would like to see in the core. |
You're creating service locators using a convention to generate its keys. It's pretty easy right now to get collections of services without writting any DI pass (eg with So, here, you're seeking for a way to express how the keys should be generated. A custom tag + DI pass does the job, but you're wondering if some more generic mechanism could allow reducing the need for custom code. At least that's what I understood so far :) |
@nicolas Exactly, thanks, I didn't know how to ask correctly. If I used tagged services, all would be instantiated and I would loose speed. In real site, having 50+ components is likely expected. Even if |
I removed the first part in your description because I think it's not needed to explain your point. Reopening. |
I recently asked @ro0NL about this possibility that Basically:
I would like something like this: services:
task_worker_locator:
class: Symfony\Component\DependencyInjection\ServiceLocator
arguments: ['!tagged task_worker']
tags: ['container.service_locator'] instead of actual: class WorkerCompilerPass implements CompilerPassInterface
{
use PriorityTaggedServiceTrait;
public function process(ContainerBuilder $container)
{
$definition = $container->findDefinition('task_worker_locator');
$services = [];
foreach ($this->findAndSortTaggedServices('task_worker', $container) as $reference) {
$services[(string) $reference] = $reference;
}
$definition->replaceArgument(0, $services);
}
} later we can do this |
Also: |
This would be useful for me too, I'm doing something like:
(A factory uses this to select service at runtime using an env DSN) So in my case I want to get a specific key for each service that isn't just the ID. Maybe there's a convention we can use like:
? Then we could do something app-specific with Autoconfiguration to generate those keys |
@ciaranmcnulty that's almost what we're working on with @deguif, to be submitted at SFCon's hack day :) |
@nicolas-grekas Damn I don't think I'm at the hack day but let's talk about it :-) |
See #29598 |
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader * [x] Support YAML loader * [x] Support XML loader (update XSD too) * [x] Add tests
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader * [x] Support YAML loader * [x] Support XML loader (update XSD too) * [x] Add tests
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader/dumper * [x] Support YAML loader/dumper * [x] Support XML loader/dump (update XSD too) * [x] Add tests
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader/dumper * [x] Support YAML loader/dumper * [x] Support XML loader/dump (update XSD too) * [x] Add tests
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader/dumper * [x] Support YAML loader/dumper * [x] Support XML loader/dump (update XSD too) * [x] Add tests
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader/dumper * [x] Support YAML loader/dumper * [x] Support XML loader/dump (update XSD too) * [x] Add tests
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader/dumper * [x] Support YAML loader/dumper * [x] Support XML loader/dump (update XSD too) * [x] Add tests
| Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yno | Tests pass? | yes | Fixed tickets | symfony#29203 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This is the continuity of the PR # Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged { tag: 'foo'', index_by: 'tag_attribute_name', default_index_method: 'static_method'} ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader/dumper * [x] Support YAML loader/dumper * [x] Support XML loader/dump (update XSD too) * [x] Add tests
Implemented in #30257, please have a look. |
This is amazing! Just checked the code and I really like that method name is specified in TaggedIteratorArgument. |
…ged collection (deguif, XuruDragon) This PR was merged into the 4.3-dev branch. Discussion ---------- [DependencyInjection] Allow to choose an index for tagged collection | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #29203 | License | MIT | Doc PR | symfony/symfony-docs#11009 This is the continuity of the PR #29598 Add a way to specify an index based on a tag attribute when injecting a tag collection into services, but also a a way to fallback to a static method on the service class. ```yaml services: foo_service: class: Foo tags: - foo foo_service_tagged: class: Bar arguments: - !tagged tag: 'foo' index_by: 'tag_attribute_name' default_index_method: 'static_method' ``` ```xml <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="foo" class="Foo"> <tag name="foo_tag" /> </service> <service id="foo_tagged_iterator" class="Bar" public="true"> <argument type="tagged" tag="foo_tag" index-by="tag_attribute_name" default-index-method="static_method" /> </service> </services> </container> ``` Tasks * [x] Support PHP loader/dumper * [x] Support YAML loader/dumper * [x] Support XML loader/dumper (and update XSD too) * [x] Add tests * [x] Documentation Commits ------- 101bfd7 [DI] change name to tag + add XMl support + adding yaml/xml tests 845d3a6 Allow to choose an index for tagged collection
#30348 is now merged, time to try it. |
@nicolas-grekas on Twitter asked me to create RFC. And when Symfony core member makes a call, you answer that call 😄
Is it possible to have autowiring for Service Locator? Example:
Because components need custom name instead of FQCN, programmer has to implement interface (otherwise, it works as usual FQCN as name):
so when I make class that implements TagCollectionInterface:
$factories is populated as
instead of
Right now I have to write a compiler pass:
It is pretty messy code, but the thing is that I make array of components where key is read from
ComponentInterface::getName()
static method. The rest (like $map variable) is irrelevant to Symfony.Anyway, tell me what you think. This idea will be scraped, I have better idea now (using annotations on controller + kernel.view event), define route tree just like NG and it will be good to go. It will not change the speed but will clean the code.
The text was updated successfully, but these errors were encountered: