symfony icon indicating copy to clipboard operation
symfony copied to clipboard

Factory named arguments wiring issue

Open v-m-i opened this issue 1 year ago • 3 comments

Symfony version(s) affected

6.2.3 and 5.4.16

Description

If we have a factory that looks like this:

final class ExampleFactory
{
    public function __invoke(
        string $first = '',
        string $second = '',
    ): ExampleService
    {...}
}

And if we use it like this (based on Passing Arguments to the Factory Method documentation):

    $services->set(ExampleFactory::class);

    $services
        ->set(ExampleCommand::class)
        ->arg('$service',
                inline_service(ExampleService::class)
                ->factory(service(ExampleFactory::class))
                ->args(
                    [
                        '$second' => 'second',
                    ]
                )
        )

The factory will be called with

$factory('second');

instead of

$factory('', 'second');

Tested on 6.2.3 and 5.4.16, but it probably affects other versions too.

How to reproduce

Bug reproducer: https://github.com/v-m-i/symfony-argument-bug

Possible Solution

No response

Additional Context

No response

v-m-i avatar Dec 29 '22 13:12 v-m-i

Did it work in a previous version of Symfony?

OskarStark avatar Dec 30 '22 09:12 OskarStark

@OskarStark I've tested it on 6.2.3 and 5.4.16, but I can test some other versions if needed. What versions should I test?

v-m-i avatar Dec 30 '22 10:12 v-m-i

Not sure, I just wanted to understand if it worked before and you experience any issues after upgrading a Symfony package to the mentioned version or if it never worked based on the documentation 👍🏻

OskarStark avatar Dec 30 '22 11:12 OskarStark

Oh, yeah, I don't know if it worked before, 5.4. was the first time I've tried it.

v-m-i avatar Jan 03 '23 15:01 v-m-i

I investigated and found that the problem may be linked the inlined service. Indeed, declaring services this way totally works and passes 'second' to $second, not $first:

$services->set(ExampleService::class)
        ->factory(service(ExampleFactory::class))
        ->args([
            '$second' => 'second',
        ]);

    $services
        ->set(ExampleCommand::class)
        ->arg('$service', service(ExampleService::class))
        ->tag('console.command');

I unfortunately wasn't able to find the right fix for it, but I hope this will help 👍

alexandre-daubois avatar Jan 03 '23 21:01 alexandre-daubois

Yeah, this works as a workaround, thanks!

v-m-i avatar Jan 09 '23 08:01 v-m-i