[DI] Allow to choose an index for tagged collection#29598
[DI] Allow to choose an index for tagged collection#29598deguif wants to merge 1 commit intosymfony:masterfrom
Conversation
nicolas-grekas
left a comment
There was a problem hiding this comment.
really nice :) This will work for iterators. The next step would be to make it work for locators also, using eg:
!service_locator !tagged {name: foo, index_by: bar}
| if (\is_string($argument) && $argument) { | ||
| return new TaggedIteratorArgument($argument); | ||
| } elseif (\is_array($argument) && isset($argument['name']) && $argument['name']) { | ||
| return new TaggedIteratorArgument($argument['name'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null); |
There was a problem hiding this comment.
to ease spotting typos, we should validate that there are no extra keys
| continue; | ||
| } | ||
|
|
||
| if (null === $defaultIndexMethod) { |
There was a problem hiding this comment.
when no $defaultIndexMethod is provided, we should imho derivate a conventional one from the attribute name.
My suggestion would be to camel-case the attribute name "foo_bar" and build something like "getDefaultFooBarName":
$defaultIndexMethod = 'getDefault'.str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $indexAttribute))).'Name';
There was a problem hiding this comment.
I see the interest in the default method fallback.
But how can be handled the fact that sometime I don't want to fallback on a method and always require a tag attribute to be defined, should I pass an empty string eg. '' to handle this case?
For example: !tagged {name: 'tag_name', index_by: 'tag_attribute', default_index_method: ''}
There was a problem hiding this comment.
I'm not sure this use case exists. Why would a tagged iterator care? That's not its job to me.
There was a problem hiding this comment.
Ok what you mean, is that there should always be a fallback method, and this fallback method is by default auto generated from the above strategy.
What I can do is only override this default by providing one explicitly?
There was a problem hiding this comment.
correct - in case the convention doesn't suit you
There was a problem hiding this comment.
Behaviour is now updated
a2041eb to
b750077
Compare
| { | ||
| $services = array(); | ||
|
|
||
| if (null === $indexAttribute && null !== $defaultIndexMethod) { |
There was a problem hiding this comment.
is this really required? i might want to "key by method" as a default approach
There was a problem hiding this comment.
It is: one must have a way to configure the key they want using configuration. The command example is again enlightening: it must be possible to ignore the default command name and let configuration take over the real command name. Same here.
|
alternatively if index_by is null we follow the convention mentioned above to find a default method (is_method=true). |
|
@ro0NL nope, really, see above comment. |
|
Wait, got ya ... an |
b750077 to
1b5b1f8
Compare
5006043 to
f40903e
Compare
|
This is exactly what I am looking for, is it possible to have some kind of fallback and use class name for index_by? |
|
@kunicmarko20 the fallback exists: create the static method covers all use cases and reduces complexity, no need for anything else IMHO. |
|
It isn't really a fallback if I have to create a method and return the class name, but at least better than me creating compiler pass all the time, thank you! great addition! |
f40903e to
2b54bec
Compare
2b54bec to
17d9fae
Compare
…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
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.
!tagged {name: 'tag_name', index_by: 'tag_attribute_name', default_index_method: 'static_method'}Tasks