@@ -332,26 +332,31 @@ if you are using Doctrine, the matching column definition should use the type ``
332332Accessing the Workflow in a Class
333333---------------------------------
334334
335- You can use the workflow inside a class by using
336- :doc: `service autowiring </service_container/autowiring >` and using
337- ``camelCased workflow name + Workflow `` as parameter name. If it is a state
338- machine type, use ``camelCased workflow name + StateMachine ``::
335+ Symfony creates a service for each workflow you define. You have two ways of
336+ injecting each workflow in any service or controller:
337+
338+ **(1) Use a specific argument name **
339+
340+ Type-hint your construtor/method argument with ``WorkflowInterface `` and name the
341+ argument using this pattern: "workflow name in camelCase" + ``Workflow `` suffix.
342+ If it is a state machine type, use the ``StateMachine `` suffix.
343+
344+ For example, to inject the ``blog_publishing `` workflow defined earlier::
339345
340346 use App\Entity\BlogPost;
341347 use Symfony\Component\Workflow\WorkflowInterface;
342348
343349 class MyClass
344350 {
345351 public function __construct(
346- // Symfony will inject the 'blog_publishing' workflow configured before
347352 private WorkflowInterface $blogPublishingWorkflow,
348353 ) {
349354 }
350355
351356 public function toReview(BlogPost $post): void
352357 {
353- // Update the currentState on the post
354358 try {
359+ // update the currentState on the post
355360 $this->blogPublishingWorkflow->apply($post, 'to_review');
356361 } catch (LogicException $exception) {
357362 // ...
@@ -360,36 +365,35 @@ machine type, use ``camelCased workflow name + StateMachine``::
360365 }
361366 }
362367
363- To get the enabled transition of a Workflow, you can use
364- :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
365- method.
368+ **(2) Use the ``#[Target]`` attribute **
366369
367- .. versionadded :: 7.1
370+ When :ref: `dealing with multiple implementations of the same type <autowiring-multiple-implementations-same-type >`
371+ the ``#[Target] `` attribute helps you select which one to inject. Symfony creates
372+ a target with the same name as each workflow.
368373
369- The :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
370- method was introduced in Symfony 7.1.
374+ For example, to select the ``blog_publishing `` lock defined earlier::
371375
372- Workflows can also be injected thanks to their name and the
373- :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ Target `
374- attribute::
375-
376- use App\Entity\BlogPost;
377376 use Symfony\Component\DependencyInjection\Attribute\Target;
378377 use Symfony\Component\Workflow\WorkflowInterface;
379378
380379 class MyClass
381380 {
382381 public function __construct(
383- #[Target('blog_publishing')]
384- private WorkflowInterface $workflow
382+ #[Target('blog_publishing')] private WorkflowInterface $workflow,
385383 ) {
386384 }
387385
388386 // ...
389387 }
390388
391- This allows you to decorrelate the argument name of any implementation
392- name.
389+ To get the enabled transition of a Workflow, you can use
390+ :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
391+ method.
392+
393+ .. versionadded :: 7.1
394+
395+ The :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
396+ method was introduced in Symfony 7.1.
393397
394398.. tip ::
395399
@@ -415,6 +419,48 @@ name.
415419 You can find the list of available workflow services with the
416420 ``php bin/console debug:autowiring workflow `` command.
417421
422+ Injecting Multiple Workflows
423+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
424+
425+ Use the :ref: `AutowireLocator <service-locator_autowire-locator >` attribute to
426+ lazy-load all workflows and get the one you need::
427+
428+ use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
429+ use Symfony\Component\DependencyInjection\ServiceLocator;
430+
431+ class MyClass
432+ {
433+ public function __construct(
434+ // 'workflow' is the service tag name and injects both workflows and state machines;
435+ // 'name' tells Symfony to index services using that tag property
436+ #[AutowireLocator('workflow', 'name')]
437+ private ServiceLocator $workflows,
438+ ) {
439+ }
440+
441+ public function someMethod(): void
442+ {
443+ // if you use the 'name' tag property to index services (see constructor above),
444+ // you can get workflows by their name; otherwise, you must use the full
445+ // service name with the 'workflow.' prefix (e.g. 'workflow.user_registration')
446+ $workflow = $this->workflows->get('user_registration');
447+
448+ // ...
449+ }
450+ }
451+
452+ .. tip ::
453+
454+ You can also inject only workflows or only state machines::
455+
456+ public function __construct(
457+ #[AutowireLocator('workflow.workflow', 'name')]
458+ private ServiceLocator $workflows,
459+ #[AutowireLocator('workflow.state_machine', 'name')]
460+ private ServiceLocator $stateMachines,
461+ ) {
462+ }
463+
418464.. _workflow_using-events :
419465
420466Using Events
0 commit comments