zenstruck / console-extra

A modular set of features to reduce configuration boilerplate for your Symfony commands.
MIT License
78 stars 3 forks source link

Support using DI attributes in `__invoke()` (requires Symfony 6.2) #43

Closed tacman closed 1 year ago

tacman commented 1 year ago

Unlike other services, injecting a stateMachine during invoke throws an exception:

    public function __invoke(
        IO                     $io,
        WorkflowInterface  $catalogStateMachine
In CheckExceptionOnInvalidReferenceBehaviorPass.php line 83:

  The service ".service_locator.Va9WIi3" has a dependency on a non-existent service "Symfony\Component\Workflow\WorkflowInterface".  

I wonder if it has to do with the ability to inject a specific service by name, rather than just type. Injecting via the constructor works as expected.

    public function __construct(private WorkflowInterface  $catalogStateMachine, string $name = null)
    {
        parent::__construct($name);
    }

    public function __invoke(
        IO                     $io,
kbond commented 1 year ago

Ah, yes, this is because under the hood, the invokable command is a ServiceSubscriber which doesn't support the named aliases.

Luckily, Symfony 6.2 makes it possible to create a workaround. Needs some work in this library but this is what should be possible:

public function __invoke(
    IO $io,

    #[Target('catalogStateMachine')]
    WorkflowInterface $stateMachine,
kbond commented 1 year ago

We can possibly always add the target attribute with the name of the parameter so you wouldn't need to add the Target attribute yourself. Not sure if this would have unintended side-effects though.

kbond commented 1 year ago

We can possibly always add the target attribute with the name of the parameter so you wouldn't need to add the Target attribute yourself. Not sure if this would have unintended side-effects though.

Discovered I cannot do this without side effects: https://github.com/symfony/symfony/issues/48555