Skip to content

Commit 16a2d8c

Browse files
committed
feat(code): progress on immutable-setter usage
The definitions have been improved. The calls have been updated.
1 parent 439dc39 commit 16a2d8c

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

service_container/calls.rst

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,74 @@ To configure the container to call the ``setLogger`` method, use the ``calls`` k
7171
7272
$container->register(MessageGenerator::class)
7373
->addMethodCall('setLogger', [new Reference('logger')]);
74+
75+
When it comes to optional dependencies, the setter approach can be useful but
76+
what if you need to change the injected dependency without mutating the initial service?
77+
78+
To do so, you probably could use `immutable-setter` injection::
79+
80+
namespace App\Service;
81+
82+
use Psr\Log\LoggerInterface;
83+
84+
class MessageGenerator
85+
{
86+
private $logger;
87+
88+
/**
89+
* @return static
90+
*/
91+
public function withLogger(LoggerInterface $logger)
92+
{
93+
$new = clone $this;
94+
$new->logger = $logger;
95+
96+
return $new;
97+
}
98+
99+
// ...
100+
}
101+
102+
In order to use this approach fully, just adapt the container configuration:
103+
104+
.. configuration-block::
105+
106+
.. code-block:: yaml
107+
108+
# config/services.yaml
109+
services:
110+
App\Service\MessageGenerator:
111+
# ...
112+
calls:
113+
- method: setLogger
114+
arguments:
115+
- '@logger'
116+
use_result: true
117+
118+
.. code-block:: xml
119+
120+
<!-- config/services.xml -->
121+
<?xml version="1.0" encoding="UTF-8" ?>
122+
<container xmlns="http://symfony.com/schema/dic/services"
123+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
124+
xsi:schemaLocation="http://symfony.com/schema/dic/services
125+
http://symfony.com/schema/dic/services/services-1.0.xsd">
126+
127+
<services>
128+
<service id="App\Service\MessageGenerator">
129+
<!-- ... -->
130+
<call method="setLogger" use-result="true">
131+
<argument type="service" id="logger" />
132+
</call>
133+
</service>
134+
</services>
135+
</container>
136+
137+
.. code-block:: php
138+
139+
// config/services.php
140+
use App\Service\MessageGenerator;
141+
use Symfony\Component\DependencyInjection\Reference;
142+
143+
$container->register(MessageGenerator::class)
144+
->addMethodCall('setLogger', [new Reference('logger')], true);

service_container/definitions.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ any method calls in the definitions as well::
117117
// configures a new method call
118118
$definition->addMethodCall('setLogger', [new Reference('logger')]);
119119

120+
// configure immutable-setter
121+
$definition->addMethodCall('withLogger', [new Reference('logger')], true);
122+
120123
// replaces all previously configured method calls with the passed array
121124
$definition->setMethodCalls($methodCalls);
122125

0 commit comments

Comments
 (0)