Skip to content

Commit 5af80af

Browse files
[DependencyInjection] Add #[AutowireCallable] and #[AutowireServiceClosure]
1 parent 166b470 commit 5af80af

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

reference/attributes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ Dependency Injection
3434
* :ref:`Autoconfigure <lazy-services_configuration>`
3535
* :ref:`AutoconfigureTag <di-instanceof>`
3636
* :ref:`Autowire <autowire-attribute>`
37+
* :ref:`AutowireCallable <container_closure-as-argument>`
3738
* :doc:`AutowireDecorated </service_container/service_decoration>`
39+
* :doc:`AutowireServiceClosure </service_container/service_closures>`
3840
* :ref:`Exclude <service-psr4-loader>`
3941
* :ref:`TaggedIterator <tags_reference-tagged-services>`
4042
* :ref:`TaggedLocator <service-subscribers-locators_defining-service-locator>`

service_container.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,8 @@ For a full list of *all* possible services in the container, run:
702702
703703
$ php bin/console debug:container
704704
705+
.. _container_closure-as-argument:
706+
705707
Injecting a Closure as an Argument
706708
----------------------------------
707709

@@ -796,6 +798,51 @@ Our configuration looks like this:
796798

797799
The ``closure`` argument type was introduced in Symfony 6.1.
798800

801+
It is also possible to convert a callable into an injected closure
802+
thanks to the
803+
:class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireCallable`
804+
attribute. Let's say our ``MessageHashGenerator`` class now has a ``generate()``
805+
method::
806+
807+
// src/Hash/MessageHashGenerator.php
808+
namespace App\Hash;
809+
810+
class MessageHashGenerator
811+
{
812+
public function generate(): string
813+
{
814+
// Compute and return a message hash
815+
}
816+
}
817+
818+
We can inject the ``generate()`` method of the ``MessageHashGenerator``
819+
like this::
820+
821+
// src/Service/MessageGenerator.php
822+
namespace App\Service;
823+
824+
use App\Hash\MessageHashGenerator;
825+
use Psr\Log\LoggerInterface;
826+
use Symfony\Component\DependencyInjection\Attribute\AutowireCallable;
827+
828+
class MessageGenerator
829+
{
830+
public function __construct(
831+
private readonly LoggerInterface $logger,
832+
#[AutowireCallable(service: MessageHashGenerator::class, method: 'generate')]
833+
private readonly \Closure $generateMessageHash
834+
) {
835+
// ...
836+
}
837+
838+
// ...
839+
}
840+
841+
.. versionadded:: 6.3
842+
843+
The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireCallable`
844+
attribute was introduced in Symfony 6.3.
845+
799846
.. _services-binding:
800847

801848
Binding Arguments by Name or Type

service_container/service_closures.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,44 @@ argument of type ``service_closure``:
9292
Another way to inject services lazily is via a
9393
:doc:`service locator </service_container/service_subscribers_locators>`.
9494

95+
Thanks to the
96+
:class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireServiceClosure`
97+
attribute, defining a service wrapped in a closure can directly be done
98+
in the service class, without further configuration::
99+
100+
// src/Service/MyService.php
101+
namespace App\Service;
102+
103+
use Symfony\Component\DependencyInjection\Attribute\AutowireServiceClosure;
104+
use Symfony\Component\Mailer\MailerInterface;
105+
106+
class MyService
107+
{
108+
public function __construct(
109+
#[AutowireServiceClosure('mailer')]
110+
private readonly \Closure $mailer
111+
) {
112+
$this->mailer = $mailer;
113+
}
114+
115+
public function doSomething(): void
116+
{
117+
// ...
118+
119+
$this->getMailer()->send($email);
120+
}
121+
122+
private function getMailer(): MailerInterface
123+
{
124+
return ($this->mailer)();
125+
}
126+
}
127+
128+
.. versionadded:: 6.3
129+
130+
The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireServiceClosure`
131+
attribute was introduced in Symfony 6.3.
132+
95133
Using a Service Closure in a Compiler Pass
96134
------------------------------------------
97135

0 commit comments

Comments
 (0)