Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0da6fc7

Browse filesBrowse files
committed
[DI] Add section about Service Closures
1 parent 43e7718 commit 0da6fc7
Copy full SHA for 0da6fc7

File tree

3 files changed

+94
-1
lines changed
Filter options

3 files changed

+94
-1
lines changed

‎service_container/lazy_services.rst

Copy file name to clipboardExpand all lines: service_container/lazy_services.rst
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Lazy Services
66

77
.. seealso::
88

9-
Another way to inject services lazily is via a :doc:`service subscriber </service_container/service_subscribers_locators>`.
9+
Other ways to inject services lazily is via a :doc:`service closure </service_container/service_closures>` or
10+
:doc:`service subscriber </service_container/service_subscribers_locators>`.
1011

1112
Why Lazy Services?
1213
------------------
+88Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
.. index::
2+
single: DependencyInjection; Service Closures
3+
4+
Service Closures
5+
================
6+
7+
This feature wraps the injected service into a closure allowing it to be
8+
lazily loaded when and if needed.
9+
This is useful if the service being injected is a bit heavy to instantiate
10+
or is used only in certain cases.
11+
The service is instantiated the first time the closure is called, while
12+
all subsequent calls return the same instance, unless the service is
13+
:doc:`not shared </service_container/shared>`::
14+
15+
// src/Service/MyService.php
16+
namespace App\Service;
17+
18+
use Symfony\Component\Mailer\MailerInterface;
19+
20+
class MyService
21+
{
22+
/**
23+
* @var \Closure
24+
*/
25+
private $mailer;
26+
27+
public function __construct(\Closure $mailer)
28+
{
29+
$this->mailer = $mailer;
30+
}
31+
32+
public function doSomething(): void
33+
{
34+
// ...
35+
36+
$this->getMailer()->send($email);
37+
}
38+
39+
private function getMailer(): MailerInterface
40+
{
41+
return ($this->mailer)();
42+
}
43+
}
44+
45+
To define a service closure and inject it to another service, create an
46+
argument of type ``service_closure``:
47+
48+
.. configuration-block::
49+
50+
.. code-block:: yaml
51+
52+
# config/services.yaml
53+
services:
54+
App\Service\MyService:
55+
arguments: [!service_closure '@mailer']
56+
57+
.. code-block:: xml
58+
59+
<!-- config/services.xml -->
60+
<?xml version="1.0" encoding="UTF-8" ?>
61+
<container xmlns="http://symfony.com/schema/dic/services"
62+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
63+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
64+
65+
<services>
66+
67+
<service id="App\Service\MyService">
68+
<argument type="service_closure" id="mailer"/>
69+
</service>
70+
71+
</services>
72+
</container>
73+
74+
.. code-block:: php
75+
76+
// config/services.php
77+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
78+
79+
use App\Service\MyService;
80+
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
81+
use Symfony\Component\DependencyInjection\Reference;
82+
83+
return function (ContainerConfigurator $configurator) {
84+
$services = $configurator->services();
85+
86+
$services->set(MyService::class)
87+
->args([new ServiceClosureArgument(new Reference('mailer'))]);
88+
};

‎service_container/service_subscribers_locators.rst

Copy file name to clipboardExpand all lines: service_container/service_subscribers_locators.rst
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ instantiation of the services to be lazy. However, that's not possible using
1212
the explicit dependency injection since services are not all meant to
1313
be ``lazy`` (see :doc:`/service_container/lazy_services`).
1414

15+
.. seealso::
16+
17+
Another way to inject services lazily is via a :doc:`service closure </service_container/service_closures>`.
18+
1519
This can typically be the case in your controllers, where you may inject several
1620
services in the constructor, but the action called only uses some of them.
1721
Another example are applications that implement the `Command pattern`_

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.