skip to Main Content

The Symfony 6.4 docs state concerning the workflow registry:

Beware that injecting the Registry into your services is not
recommended.

However, I need to get a specific workflow within a service method which decides which workflow to use based on a key. I don’t know in advance which workflow to load, so I can’t inject a specific workflow. How can I do this? For now, I inject the registry. Could I somehow inject the service_container and get it from there later?

2

Answers


  1. Chosen as BEST ANSWER

    Here's my Solution:

        #WorkflowLoader.php
    use PsrContainerContainerExceptionInterface;
    use PsrContainerContainerInterface;
    use PsrContainerNotFoundExceptionInterface;
    use SymfonyComponentDependencyInjectionAttributeTaggedLocator;
    use SymfonyComponentWorkflowWorkflow;
    use RuntimeException;
    
    class WorkflowLoader
    {
        public function __construct(
            #[TaggedLocator('workflow')] private readonly ContainerInterface $serviceLocator
        )
        {
        }
    
        public function getWorkflow($workflowName): Workflow
        {
            try {
                if (!$workflow = $this->serviceLocator->get('state_machine.' . $workflowName)) {
                    $workflow = $this->serviceLocator->get('workflow.' . $workflowName);
                }
            } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
                throw new RuntimeException("Process Workflow $workflowName could not be loaded. n" . $e->getMessage());
            }
            return $workflow;
        }
    }
    

  2. You can use service locators to access every workflows.

    It’s mentioned in the documentation:

    If you want to retrieve all workflows, for documentation purposes for example, you can inject all services with the following tag:

    workflow: all workflows and all state machine;
    workflow.workflow: all workflows;
    workflow.state_machine: all state machines.
    

    It’s possible to do it easily with Symfony 6/7 using locator attribute:

    public function __construct(
        #[TaggedLocator('workflow')] private ContainerInterface $workflowsAndStateMachinesLocator,
        #[TaggedLocator('workflow.workflow')] private ContainerInterface $workflowsLocator,
        #[TaggedLocator('workflow.state_machine')] private ContainerInterface $stateMachinesLocator,
    ) {
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search