@@ -530,26 +530,31 @@ if you are using Doctrine, the matching column definition should use the type ``
530530Accessing the Workflow in a Class
531531---------------------------------
532532
533- You can use the workflow inside a class by using
534- :doc: `service autowiring </service_container/autowiring >` and using
535- ``camelCased workflow name + Workflow `` as parameter name. If it is a state
536- machine type, use ``camelCased workflow name + StateMachine ``::
533+ Symfony creates a service for each workflow you define. You have two ways of
534+ injecting each workflow in any service or controller:
535+
536+ **(1) Use a specific argument name **
537+
538+ Type-hint your construtor/method argument with ``WorkflowInterface `` and name the
539+ argument using this pattern: "workflow name in camelCase" + ``Workflow `` suffix.
540+ If it is a state machine type, use the ``StateMachine `` suffix.
541+
542+ For example, to inject the ``blog_publishing `` workflow defined earlier::
537543
538544 use App\Entity\BlogPost;
539545 use Symfony\Component\Workflow\WorkflowInterface;
540546
541547 class MyClass
542548 {
543549 public function __construct(
544- // Symfony will inject the 'blog_publishing' workflow configured before
545550 private WorkflowInterface $blogPublishingWorkflow,
546551 ) {
547552 }
548553
549554 public function toReview(BlogPost $post): void
550555 {
551- // Update the currentState on the post
552556 try {
557+ // update the currentState on the post
553558 $this->blogPublishingWorkflow->apply($post, 'to_review');
554559 } catch (LogicException $exception) {
555560 // ...
@@ -558,31 +563,30 @@ machine type, use ``camelCased workflow name + StateMachine``::
558563 }
559564 }
560565
561- To get the enabled transition of a Workflow, you can use
562- :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
563- method.
566+ **(2) Use the ``#[Target]`` attribute **
564567
565- Workflows can also be injected thanks to their name and the
566- :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ Target `
567- attribute::
568+ When :ref: `dealing with multiple implementations of the same type <autowiring-multiple-implementations-same-type >`
569+ the ``#[Target] `` attribute helps you select which one to inject. Symfony creates
570+ a target with the same name as each workflow.
571+
572+ For example, to select the ``blog_publishing `` lock defined earlier::
568573
569- use App\Entity\BlogPost;
570574 use Symfony\Component\DependencyInjection\Attribute\Target;
571575 use Symfony\Component\Workflow\WorkflowInterface;
572576
573577 class MyClass
574578 {
575579 public function __construct(
576- #[Target('blog_publishing')]
577- private WorkflowInterface $workflow
580+ #[Target('blog_publishing')] private WorkflowInterface $workflow,
578581 ) {
579582 }
580583
581584 // ...
582585 }
583586
584- This allows you to decorrelate the argument name of any implementation
585- name.
587+ To get the enabled transition of a Workflow, you can use
588+ :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
589+ method.
586590
587591.. tip ::
588592
@@ -604,6 +608,48 @@ name.
604608 You can find the list of available workflow services with the
605609 ``php bin/console debug:autowiring workflow `` command.
606610
611+ Injecting Multiple Workflows
612+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
613+
614+ Use the :ref: `AutowireLocator <service-locator_autowire-locator >` attribute to
615+ lazy-load all workflows and get the one you need::
616+
617+ use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
618+ use Symfony\Component\DependencyInjection\ServiceLocator;
619+
620+ class MyClass
621+ {
622+ public function __construct(
623+ // 'workflow' is the service tag name and injects both workflows and state machines;
624+ // 'name' tells Symfony to index services using that tag property
625+ #[AutowireLocator('workflow', 'name')]
626+ private ServiceLocator $workflows,
627+ ) {
628+ }
629+
630+ public function someMethod(): void
631+ {
632+ // if you use the 'name' tag property to index services (see constructor above),
633+ // you can get workflows by their name; otherwise, you must use the full
634+ // service name with the 'workflow.' prefix (e.g. 'workflow.user_registration')
635+ $workflow = $this->workflows->get('user_registration');
636+
637+ // ...
638+ }
639+ }
640+
641+ .. tip ::
642+
643+ You can also inject only workflows or only state machines::
644+
645+ public function __construct(
646+ #[AutowireLocator('workflow.workflow', 'name')]
647+ private ServiceLocator $workflows,
648+ #[AutowireLocator('workflow.state_machine', 'name')]
649+ private ServiceLocator $stateMachines,
650+ ) {
651+ }
652+
607653.. _workflow_using-events :
608654
609655Using Events
0 commit comments