Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d417f7b

Browse files
committed
[#2972] Many small tweaks - thanks very much to @wouterj and @xabbuh
1 parent c5ae3dd commit d417f7b

File tree

2 files changed

+63
-41
lines changed

2 files changed

+63
-41
lines changed

book/service_container.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ Injecting the dependency by the setter method just needs a change of syntax:
754754
and "setter injection". The Symfony2 service container also supports
755755
"property injection".
756756

757+
.. _book-container-request-stack:
758+
757759
Injecting the Request
758760
~~~~~~~~~~~~~~~~~~~~~
759761

cookbook/service_container/scopes.rst

Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ This entry is all about scopes, a somewhat advanced topic related to the
1212

1313
If you are trying to inject the ``request`` service, the simple solution
1414
is to inject the ``request_stack`` service instead and access the current
15-
Request by calling the ``getCurrentRequest()`` method. The rest of this
16-
entry talks about scopes in a theoretical and more advanced way. If you're
17-
dealing with scopes for the ``request`` service, simply inject ``request_stack``.
15+
Request by calling the ``getCurrentRequest()`` method (see :ref:`book-container-request-stack`).
16+
The rest of this entry talks about scopes in a theoretical and more advanced
17+
way. If you're dealing with scopes for the ``request`` service, simply
18+
inject ``request_stack``.
1819

1920
Understanding Scopes
2021
--------------------
@@ -34,8 +35,8 @@ also defines a third scope: ``request``. This scope is tied to the request,
3435
meaning a new instance is created for each subrequest and is unavailable
3536
outside the request (for instance in the CLI).
3637

37-
The Example: client Scope
38-
~~~~~~~~~~~~~~~~~~~~~~~~~
38+
An Example: client Scope
39+
~~~~~~~~~~~~~~~~~~~~~~~~
3940

4041
Other than the ``request`` service (which has a simple solution, see the
4142
above note), no services in the default Symfony2 container belong to any
@@ -64,14 +65,14 @@ when compiling the container. Read the sidebar below for more details.
6465
from it, such as what the "sender" address should be. You add it as a
6566
constructor argument. Let's look at why this presents a problem:
6667

67-
* When requesting ``my_mailer``, an instance of ``my_mailer`` (let's call
68-
it *MailerA*) is created and the ``client_configuration`` service (let's
69-
call it *ConfigurationA*) is passed to it. Life is good!
68+
* When requesting ``my_mailer``, an instance of ``my_mailer`` (called
69+
*MailerA* here) is created and the ``client_configuration`` service (
70+
called *ConfigurationA* here) is passed to it. Life is good!
7071

7172
* Your application now needs to do something with another client, and
7273
you've architected your application in such a way that you handle this
7374
by entering a new ``client_configuration`` scope and setting a new
74-
``client_configuration`` service into the container. Let's call this
75+
``client_configuration`` service into the container. Call this
7576
*ConfigurationB*.
7677

7778
* Somewhere in your application, you once again ask for the ``my_mailer``
@@ -96,14 +97,14 @@ Using a Service from a narrower Scope
9697

9798
There are several solutions to the scope problem:
9899

99-
* Use setter injection if the dependency is "synchronized"; (see
100+
* A) Use setter injection if the dependency is "synchronized"; (see
100101
:ref:`using-synchronized-service`).
101102

102-
* Put your service in the same scope as the dependency (or a narrower one). If
103+
* B) Put your service in the same scope as the dependency (or a narrower one). If
103104
you depend on the ``client_configuration`` service, this means putting your
104105
new service in the ``client`` scope (see :ref:`changing-service-scope`);
105106

106-
* Pass the entire container to your service and retrieve your dependency from
107+
* C) Pass the entire container to your service and retrieve your dependency from
107108
the container each time you need it to be sure you have the right instance
108109
-- your service can live in the default ``container`` scope (see
109110
:ref:`passing-container`);
@@ -112,15 +113,15 @@ Each scenario is detailed in the following sections.
112113

113114
.. _using-synchronized-service:
114115

115-
Using a synchronized Service
116-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116+
A) Using a synchronized Service
117+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117118

118119
.. versionadded:: 2.3
119120
Synchronized services are new in Symfony 2.3.
120121

121-
Injecting the container or setting your service to a narrower scope have
122+
Both injecting the container and setting your service to a narrower scope have
122123
drawbacks. Assume first that the ``client_configuration`` service has been
123-
marked as "synchronized":
124+
marked as ``synchronized``:
124125

125126
.. configuration-block::
126127

@@ -132,17 +133,25 @@ marked as "synchronized":
132133
class: Acme\HelloBundle\Client\ClientConfiguration
133134
scope: client
134135
synchronized: true
136+
# ...
135137
136138
.. code-block:: xml
137139
138140
<!-- app/config/config.xml -->
139141
<?xml version="1.0" encoding="UTF-8" ?>
140142
<container xmlns="http://symfony.com/schema/dic/services"
141143
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
142-
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
144+
xsi:schemaLocation="http://symfony.com/schema/dic/services
145+
http://symfony.com/schema/dic/services/services-1.0.xsd"
146+
>
143147
144148
<services>
145-
<service id="client_configuration" scope="client" synchronized="true" class="Acme\HelloBundle\Client\ClientConfiguration" />
149+
<service
150+
id="client_configuration"
151+
scope="client"
152+
synchronized="true"
153+
class="Acme\HelloBundle\Client\ClientConfiguration"
154+
/>
146155
</services>
147156
</container>
148157
@@ -151,13 +160,13 @@ marked as "synchronized":
151160
// app/config/config.php
152161
use Symfony\Component\DependencyInjection\Definition;
153162
154-
$defn = new Definition(
163+
$definition = new Definition(
155164
'Acme\HelloBundle\Client\ClientConfiguration',
156165
array()
157166
);
158-
$defn->setScope('client');
159-
$defn->setSynchronized(true);
160-
$container->setDefinition('client_configuration', $defn);
167+
$definition->setScope('client');
168+
$definition->setSynchronized(true);
169+
$container->setDefinition('client_configuration', $definition);
161170
162171
Now, if you inject this service using setter injection, there are no drawbacks
163172
and everything works without any special code in your service or in your definition::
@@ -202,20 +211,25 @@ your code. This should also be taken into account when declaring your service:
202211
203212
# src/Acme/HelloBundle/Resources/config/services.yml
204213
services:
205-
greeting_card_manager:
206-
class: Acme\HelloBundle\Mail\GreetingCardManager
214+
my_mailer:
215+
class: Acme\HelloBundle\Mail\Mailer
207216
calls:
208217
- [setClientConfiguration, ['@?client_configuration=']]
209218
210219
.. code-block:: xml
211220
212221
<!-- src/Acme/HelloBundle/Resources/config/services.xml -->
213222
<services>
214-
<service id="greeting_card_manager"
215-
class="Acme\HelloBundle\Mail\GreetingCardManager"
223+
<service id="my_mailer"
224+
class="Acme\HelloBundle\Mail\Mailer"
216225
>
217226
<call method="setClientConfiguration">
218-
<argument type="service" id="client_configuration" on-invalid="null" strict="false" />
227+
<argument
228+
type="service"
229+
id="client_configuration"
230+
on-invalid="null"
231+
strict="false"
232+
/>
219233
</call>
220234
</service>
221235
</services>
@@ -227,37 +241,43 @@ your code. This should also be taken into account when declaring your service:
227241
use Symfony\Component\DependencyInjection\ContainerInterface;
228242
229243
$definition = $container->setDefinition(
230-
'greeting_card_manager',
231-
new Definition('Acme\HelloBundle\Mail\GreetingCardManager')
244+
'my_mailer',
245+
new Definition('Acme\HelloBundle\Mail\Mailer')
232246
)
233247
->addMethodCall('setClientConfiguration', array(
234-
new Reference('client_configuration', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)
248+
new Reference(
249+
'client_configuration',
250+
ContainerInterface::NULL_ON_INVALID_REFERENCE,
251+
false
252+
)
235253
));
236254
237255
.. _changing-service-scope:
238256

239-
Changing the Scope of your Service
240-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
257+
B) Changing the Scope of your Service
258+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241259

242-
Changing the scope of a service should be done in its definition:
260+
Changing the scope of a service should be done in its definition. This example
261+
assumes that the ``Mailer`` class has a ``__construct`` function whose first
262+
argument is the ``ClientConfiguration`` object:
243263

244264
.. configuration-block::
245265

246266
.. code-block:: yaml
247267
248268
# src/Acme/HelloBundle/Resources/config/services.yml
249269
services:
250-
greeting_card_manager:
251-
class: Acme\HelloBundle\Mail\GreetingCardManager
270+
my_mailer:
271+
class: Acme\HelloBundle\Mail\Mailer
252272
scope: client
253273
arguments: [@client_configuration]
254274
255275
.. code-block:: xml
256276
257277
<!-- src/Acme/HelloBundle/Resources/config/services.xml -->
258278
<services>
259-
<service id="greeting_card_manager"
260-
class="Acme\HelloBundle\Mail\GreetingCardManager"
279+
<service id="my_mailer"
280+
class="Acme\HelloBundle\Mail\Mailer"
261281
scope="client"
262282
/>
263283
<argument type="service" id="client_configuration" />
@@ -269,17 +289,17 @@ Changing the scope of a service should be done in its definition:
269289
use Symfony\Component\DependencyInjection\Definition;
270290
271291
$definition = $container->setDefinition(
272-
'greeting_card_manager',
292+
'my_mailer',
273293
new Definition(
274-
'Acme\HelloBundle\Mail\GreetingCardManager',
294+
'Acme\HelloBundle\Mail\Mailer',
275295
array(new Reference('client_configuration'),
276296
))
277297
)->setScope('client');
278298
279299
.. _passing-container:
280300

281-
Passing the Container as a Dependency of your Service
282-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301+
C) Passing the Container as a Dependency of your Service
302+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
283303

284304
Setting the scope to a narrower one is not always possible (for instance, a
285305
twig extension must be in the ``container`` scope as the Twig environment

0 commit comments

Comments
 (0)