You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
services:
App\Handler\One:
tags: ['app.handler']App\Handler\Two:
tags: ['app.handler']App\HandlerCollection:
# inject all services tagged with app.handler as first argumentarguments:
- !tagged_iteratorapp.handler
namespaceApp;
classChainService
{
/** * @param iterable<AwesomeService> $awesomeServices */publicfunction__construct(privateiterable$awesomeServices) {}
publicfunctiondoSomething(string$string): string
{
foreach ($this->awesomeServicesas$awesomeService) {
if ($awesomeService->supports($string)) {
return$awesomeService->doSomething($string);
}
}
thrownewInvalidArgumentException(
sprintf(
'Failed to do something with "%s".',
$string,
)
);
}
}
To extinguish the need of the @param annotation in this case I would like to use a typed variable-length argument lists in the constructor instead of an iterable, like this:
namespaceApp;
classChainService
{
privatearray$awesomeServices;
publicfunction__construct(AwesomeService ...$awesomeServices) {}
publicfunctiondoSomething(string$string): string
{
foreach ($this->awesomeServicesas$awesomeService) {
if ($awesomeService->supports($string)) {
return$awesomeService->doSomething($string);
}
}
thrownewInvalidArgumentException(
sprintf(
'Failed to do something with "%s".',
$string,
)
);
}
}
The tagged_iterator is not able to deal with this code because the Dependency Injection component will try to inject an RewindableGenerator to ChainService which implements an IteratorAggregate, thus triggering a type error.
The usage of variadics in a typed constructor argument is possible when services are wired manually in services.yaml.
For example:
Can you make the tagged_iterator operational for typed variadic constructor arguments?
Or can you introduce something else to make the typed variadic constructor arguments possible?
There's a critical difference between both implementations: the non-variadic variant will not instantiate services that are listed after the one that "supports" the thing, while the variadic variant will consume the full iterator.
Personally, this style using variadics is a hack and doesn't need to be supported as such. See how the argument "removing an @param" can lead to effective and nasty runtime side effects.
Description
Injecting all tagged services to a service is possible by declaring an
iterable
within the constructor.Example:
The
services.yaml
might look like this:Example code found here:
https://symfony.com/doc/current/service_container/tags.html#reference-tagged-services
In practise my code will look like this:
To extinguish the need of the
@param
annotation in this case I would like to use a typed variable-length argument lists in the constructor instead of aniterable
, like this:The
tagged_iterator
is not able to deal with this code because the Dependency Injection component will try to inject anRewindableGenerator
toChainService
which implements anIteratorAggregate
, thus triggering a type error.The usage of variadics in a typed constructor argument is possible when services are wired manually in
services.yaml
.For example:
Can you make the
tagged_iterator
operational for typed variadic constructor arguments?Or can you introduce something else to make the typed variadic constructor arguments possible?
Example
The text was updated successfully, but these errors were encountered: