-
-
Notifications
You must be signed in to change notification settings - Fork 312
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
Support for variadic arguments #619
Comments
Thanks for the detailed issue! Can you confirm that: Engine::class => \DI\autowire(UserProfile::class)
->constructor(
\DI\get(DbConnection::class),
\DI\get(Module\CasinoFollow::class),
\DI\get(Module\UserFollow::class),
\DI\get(Module\Review::class)
), doesn't work and that it injects only |
Indeed, it only injects the first module: https://i.imgur.com/BANmom5.png |
I would like to start working on this, but I don't feel so accustomed to PHP-DI internals yet. Do you have any tips @mnapoli for me? Where should I start? I have written some preliminary tests for this behavior. |
@tssge that's great! I suggest you have a look here: https://github.com/PHP-DI/PHP-DI/blob/master/src/Definition/Resolver/ParameterResolver.php#L51 You can see that we do Try to write unit tests but more importantly functional tests in here: https://github.com/PHP-DI/PHP-DI/blob/master/tests/IntegrationTest/Definitions/CreateDefinitionTest.php |
@mnapoli Don't know if you noticed, but I added pull request for this functionality. Can you check if it's of an okay quality? Would like some feedback |
@tssge yes that is awesome thanks! I had a quick look last week but because of conferences I didn't have enough time to review it carefully (this PR is more complex that other simple PRs :) ) I'll try to have a look at it this week. |
Need this feature too. |
Is it possible to make it work the same way with constructorParameter() method too? Example:
|
With the patch provided, the following should be possible: MyClass::class => DI\autowire()
->constructorParameter(0, 'foo')
->constructorParameter(1, 'bar')
->constructorParameter(2, 'baz')
->constructorParameter(3, 'etc') if the signature is something like this: class MyClass {
function __construct(string ...$strings) {}
} Multiple named parameters are not supported (as of yet at least) as the parameters are saved to an array keyed by their name. |
Not quite what I would like to do (-: Now I can avoid defining other constructor arguments and have them autowired only this way:
But I would like to type-hint $args: And define it like this:
|
You could do it this way (with the patch merged): class MyClass {
public function __construct(Foo $foo, Bar $bar, Baz $baz, string ...$args) {}
}
MyClass::class => DI\autowire()
->constructorParameter(3, 'a')
->constructorParameter(4, 'b')
->constructorParameter(5, 'c') Parameters 0 to 2 (types of Foo, Bar and Baz) would be autowired automatically without defining them as you'd expect with PHP-DI. I do not personally prefer this MyClass::class => DI\autowire()
->constructorParameter('args', ...['a', 'b', 'c', 'etc']) to work as you described, because that would show the user in the constructorParameter method signature that multiple parameters are valid to any constructor parameter, when the situation with PHP is that only the last parameter can be variadic. For example: user might think based on method signature and documentation that this would be valid: MyClass::class => DI\autowire()
->constructorParameter('bar', ...['a', 'b', 'c', 'etc'])
->constructorParameter('args', ...['a', 'b', 'c', 'etc']) When obviously the part where bar is defined would not work. I understand that you'd perhaps want to use the parameter name instead of the argument number for clarity, but I don't think it's a good idea. |
I had a quick look at this and I think it might be worth implementing the same rules as PHP 8's named parameters: https://wiki.php.net/rfc/named_params (over all the PHP-DI features) The integration with variadics is clearly defined (and constrained) in there, so it could be both a good lead to follow, as well as minimize confusion and friction down the road. |
PHP-DI does not currently support variadic arguments for autowiring. It will only inject the first element to the variadic parameter in a constructor, silently discarding the rest.
For example for this class:
cannot be autowired by:
but must be instead autowired by:
which in turn reduces the efficiency of caching I believe and is harder to debug.
The text was updated successfully, but these errors were encountered: