@@ -327,26 +327,31 @@ if you are using Doctrine, the matching column definition should use the type ``
327327Accessing the Workflow in a Class
328328---------------------------------
329329
330- You can use the workflow inside a class by using
331- :doc: `service autowiring </service_container/autowiring >` and using
332- ``camelCased workflow name + Workflow `` as parameter name. If it is a state
333- machine type, use ``camelCased workflow name + StateMachine ``::
330+ Symfony creates a service for each workflow you define. You have two ways of
331+ injecting each workflow in any service or controller:
332+
333+ **(1) Use a specific argument name **
334+
335+ Type-hint your construtor/method argument with ``WorkflowInterface `` and name the
336+ argument using this pattern: "workflow name in camelCase" + ``Workflow `` suffix.
337+ If it is a state machine type, use the ``StateMachine `` suffix.
338+
339+ For example, to inject the ``blog_publishing `` workflow defined earlier::
334340
335341 use App\Entity\BlogPost;
336342 use Symfony\Component\Workflow\WorkflowInterface;
337343
338344 class MyClass
339345 {
340346 public function __construct(
341- // Symfony will inject the 'blog_publishing' workflow configured before
342347 private WorkflowInterface $blogPublishingWorkflow,
343348 ) {
344349 }
345350
346351 public function toReview(BlogPost $post): void
347352 {
348- // Update the currentState on the post
349353 try {
354+ // update the currentState on the post
350355 $this->blogPublishingWorkflow->apply($post, 'to_review');
351356 } catch (LogicException $exception) {
352357 // ...
@@ -355,28 +360,27 @@ machine type, use ``camelCased workflow name + StateMachine``::
355360 }
356361 }
357362
358- Workflows can also be injected thanks to their name and the
359- :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ Target `
360- attribute::
363+ **(2) Use the ``#[Target]`` attribute **
364+
365+ When :ref: `dealing with multiple implementations of the same type <autowiring-multiple-implementations-same-type >`
366+ the ``#[Target] `` attribute helps you select which one to inject. Symfony creates
367+ a target with the same name as each workflow.
368+
369+ For example, to select the ``blog_publishing `` lock defined earlier::
361370
362- use App\Entity\BlogPost;
363371 use Symfony\Component\DependencyInjection\Attribute\Target;
364372 use Symfony\Component\Workflow\WorkflowInterface;
365373
366374 class MyClass
367375 {
368376 public function __construct(
369- #[Target('blog_publishing')]
370- private WorkflowInterface $workflow
377+ #[Target('blog_publishing')] private WorkflowInterface $workflow,
371378 ) {
372379 }
373380
374381 // ...
375382 }
376383
377- This allows you to decorrelate the argument name of any implementation
378- name.
379-
380384.. versionadded :: 6.2
381385
382386 All workflows and state machines services are tagged since in Symfony 6.2.
@@ -402,6 +406,48 @@ name.
402406 You can find the list of available workflow services with the
403407 ``php bin/console debug:autowiring workflow `` command.
404408
409+ Injecting Multiple Workflows
410+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
411+
412+ Use the :ref: `AutowireLocator <service-locator_autowire-locator >` attribute to
413+ lazy-load all workflows and get the one you need::
414+
415+ use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
416+ use Symfony\Component\DependencyInjection\ServiceLocator;
417+
418+ class MyClass
419+ {
420+ public function __construct(
421+ // 'workflow' is the service tag name and injects both workflows and state machines;
422+ // 'name' tells Symfony to index services using that tag property
423+ #[AutowireLocator('workflow', 'name')]
424+ private ServiceLocator $workflows,
425+ ) {
426+ }
427+
428+ public function someMethod(): void
429+ {
430+ // if you use the 'name' tag property to index services (see constructor above),
431+ // you can get workflows by their name; otherwise, you must use the full
432+ // service name with the 'workflow.' prefix (e.g. 'workflow.user_registration')
433+ $workflow = $this->workflows->get('user_registration');
434+
435+ // ...
436+ }
437+ }
438+
439+ .. tip ::
440+
441+ You can also inject only workflows or only state machines::
442+
443+ public function __construct(
444+ #[AutowireLocator('workflow.workflow', 'name')]
445+ private ServiceLocator $workflows,
446+ #[AutowireLocator('workflow.state_machine', 'name')]
447+ private ServiceLocator $stateMachines,
448+ ) {
449+ }
450+
405451.. _workflow_using-events :
406452
407453Using Events
0 commit comments