@@ -540,26 +540,31 @@ if you are using Doctrine, the matching column definition should use the type ``
540540Accessing the Workflow in a Class
541541---------------------------------
542542
543- You can use the workflow inside a class by using
544- :doc: `service autowiring </service_container/autowiring >` and using
545- ``camelCased workflow name + Workflow `` as parameter name. If it is a state
546- machine type, use ``camelCased workflow name + StateMachine ``::
543+ Symfony creates a service for each workflow you define. You have two ways of
544+ injecting each workflow in any service or controller:
545+
546+ **(1) Use a specific argument name **
547+
548+ Type-hint your construtor/method argument with ``WorkflowInterface `` and name the
549+ argument using this pattern: "workflow name in camelCase" + ``Workflow `` suffix.
550+ If it is a state machine type, use the ``StateMachine `` suffix.
551+
552+ For example, to inject the ``blog_publishing `` workflow defined earlier::
547553
548554 use App\Entity\BlogPost;
549555 use Symfony\Component\Workflow\WorkflowInterface;
550556
551557 class MyClass
552558 {
553559 public function __construct(
554- // Symfony will inject the 'blog_publishing' workflow configured before
555560 private WorkflowInterface $blogPublishingWorkflow,
556561 ) {
557562 }
558563
559564 public function toReview(BlogPost $post): void
560565 {
561- // Update the currentState on the post
562566 try {
567+ // update the currentState on the post
563568 $this->blogPublishingWorkflow->apply($post, 'to_review');
564569 } catch (LogicException $exception) {
565570 // ...
@@ -568,36 +573,35 @@ machine type, use ``camelCased workflow name + StateMachine``::
568573 }
569574 }
570575
571- To get the enabled transition of a Workflow, you can use
572- :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
573- method.
576+ **(2) Use the ``#[Target]`` attribute **
574577
575- .. versionadded :: 7.1
578+ When :ref: `dealing with multiple implementations of the same type <autowiring-multiple-implementations-same-type >`
579+ the ``#[Target] `` attribute helps you select which one to inject. Symfony creates
580+ a target with the same name as each workflow.
576581
577- The :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
578- method was introduced in Symfony 7.1.
582+ For example, to select the ``blog_publishing `` lock defined earlier::
579583
580- Workflows can also be injected thanks to their name and the
581- :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ Target `
582- attribute::
583-
584- use App\Entity\BlogPost;
585584 use Symfony\Component\DependencyInjection\Attribute\Target;
586585 use Symfony\Component\Workflow\WorkflowInterface;
587586
588587 class MyClass
589588 {
590589 public function __construct(
591- #[Target('blog_publishing')]
592- private WorkflowInterface $workflow
590+ #[Target('blog_publishing')] private WorkflowInterface $workflow,
593591 ) {
594592 }
595593
596594 // ...
597595 }
598596
599- This allows you to decorrelate the argument name of any implementation
600- name.
597+ To get the enabled transition of a Workflow, you can use
598+ :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
599+ method.
600+
601+ .. versionadded :: 7.1
602+
603+ The :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
604+ method was introduced in Symfony 7.1.
601605
602606.. tip ::
603607
@@ -623,6 +627,48 @@ name.
623627 You can find the list of available workflow services with the
624628 ``php bin/console debug:autowiring workflow `` command.
625629
630+ Injecting Multiple Workflows
631+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
632+
633+ Use the :ref: `AutowireLocator <service-locator_autowire-locator >` attribute to
634+ lazy-load all workflows and get the one you need::
635+
636+ use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
637+ use Symfony\Component\DependencyInjection\ServiceLocator;
638+
639+ class MyClass
640+ {
641+ public function __construct(
642+ // 'workflow' is the service tag name and injects both workflows and state machines;
643+ // 'name' tells Symfony to index services using that tag property
644+ #[AutowireLocator('workflow', 'name')]
645+ private ServiceLocator $workflows,
646+ ) {
647+ }
648+
649+ public function someMethod(): void
650+ {
651+ // if you use the 'name' tag property to index services (see constructor above),
652+ // you can get workflows by their name; otherwise, you must use the full
653+ // service name with the 'workflow.' prefix (e.g. 'workflow.user_registration')
654+ $workflow = $this->workflows->get('user_registration');
655+
656+ // ...
657+ }
658+ }
659+
660+ .. tip ::
661+
662+ You can also inject only workflows or only state machines::
663+
664+ public function __construct(
665+ #[AutowireLocator('workflow.workflow', 'name')]
666+ private ServiceLocator $workflows,
667+ #[AutowireLocator('workflow.state_machine', 'name')]
668+ private ServiceLocator $stateMachines,
669+ ) {
670+ }
671+
626672.. _workflow_using-events :
627673
628674Using Events
0 commit comments