Skip to content

Commit 6e2dab2

Browse files
committed
feature #5169 Removed synchronized services from Symfony 2.7 docs (javiereguiluz)
This PR was merged into the 2.7 branch. Discussion ---------- Removed synchronized services from Symfony 2.7 docs | Q | A | ------------- | --- | Doc fix? | yes | New docs? | no | Applies to | 2.7+ | Fixed tickets | #5140 Commits ------- 8a69d0e Added a label to maintain the old URL 6f2ef89 Reworded he notice about deprecation of synchronized services edde458 Removed synchronized services from Symfony 2.7 docs
2 parents b74a2ac + 8a69d0e commit 6e2dab2

File tree

1 file changed

+19
-157
lines changed

1 file changed

+19
-157
lines changed

cookbook/service_container/scopes.rst

Lines changed: 19 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
How to Work with Scopes
55
=======================
66

7-
This entry is all about scopes, a somewhat advanced topic related to the
7+
This article is all about scopes, a somewhat advanced topic related to the
88
:doc:`/book/service_container`. If you've ever gotten an error mentioning
9-
"scopes" when creating services, then this entry is for you.
9+
"scopes" when creating services, then this article is for you.
1010

1111
.. note::
1212

@@ -25,10 +25,11 @@ The scope of a service controls how long an instance of a service is used
2525
by the container. The DependencyInjection component provides two generic
2626
scopes:
2727

28-
- ``container`` (the default one): The same instance is used each time you
29-
request it from this container.
28+
``container`` (the default one):
29+
The same instance is used each time you ask for it from this container.
3030

31-
- ``prototype``: A new instance is created each time you request the service.
31+
``prototype``:
32+
A new instance is created each time you ask for the service.
3233

3334
The
3435
:class:`Symfony\\Component\\HttpKernel\\DependencyInjection\\ContainerAwareHttpKernel`
@@ -40,9 +41,9 @@ An Example: Client Scope
4041
~~~~~~~~~~~~~~~~~~~~~~~~
4142

4243
Other than the ``request`` service (which has a simple solution, see the
43-
above note), no services in the default Symfony2 container belong to any
44+
above note), no services in the default Symfony container belong to any
4445
scope other than ``container`` and ``prototype``. But for the purposes of
45-
this entry, imagine there is another scope ``client`` and a service ``client_configuration``
46+
this article, imagine there is another scope ``client`` and a service ``client_configuration``
4647
that belongs to it. This is not a common situation, but the idea is that
4748
you may enter and exit multiple ``client`` scopes during a request, and each
4849
has its own ``client_configuration`` service.
@@ -71,7 +72,7 @@ when compiling the container. Read the sidebar below for more details.
7172
called *ConfigurationA* here) is passed to it. Life is good!
7273

7374
* Your application now needs to do something with another client, and
74-
you've architected your application in such a way that you handle this
75+
you've designed your application in such a way that you handle this
7576
by entering a new ``client_configuration`` scope and setting a new
7677
``client_configuration`` service into the container. Call this
7778
*ConfigurationB*.
@@ -96,16 +97,13 @@ when compiling the container. Read the sidebar below for more details.
9697
Using a Service from a Narrower Scope
9798
-------------------------------------
9899

99-
There are several solutions to the scope problem:
100+
There are two solutions to the scope problem:
100101

101-
* A) Use setter injection if the dependency is ``synchronized`` (see
102-
:ref:`using-synchronized-service`);
103-
104-
* B) Put your service in the same scope as the dependency (or a narrower one). If
102+
* A) Put your service in the same scope as the dependency (or a narrower one). If
105103
you depend on the ``client_configuration`` service, this means putting your
106104
new service in the ``client`` scope (see :ref:`changing-service-scope`);
107105

108-
* C) Pass the entire container to your service and retrieve your dependency from
106+
* B) Pass the entire container to your service and retrieve your dependency from
109107
the container each time you need it to be sure you have the right instance
110108
-- your service can live in the default ``container`` scope (see
111109
:ref:`passing-container`).
@@ -114,151 +112,15 @@ Each scenario is detailed in the following sections.
114112

115113
.. _using-synchronized-service:
116114

117-
A) Using a Synchronized Service
118-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119-
120-
.. versionadded:: 2.3
121-
Synchronized services were introduced in Symfony 2.3.
122-
123-
Both injecting the container and setting your service to a narrower scope have
124-
drawbacks. Assume first that the ``client_configuration`` service has been
125-
marked as ``synchronized``:
126-
127-
.. configuration-block::
128-
129-
.. code-block:: yaml
130-
131-
# app/config/config.yml
132-
services:
133-
client_configuration:
134-
class: AppBundle\Client\ClientConfiguration
135-
scope: client
136-
synchronized: true
137-
synthetic: true
138-
# ...
139-
140-
.. code-block:: xml
141-
142-
<!-- app/config/config.xml -->
143-
<?xml version="1.0" encoding="UTF-8" ?>
144-
<container xmlns="http://symfony.com/schema/dic/services"
145-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
146-
xsi:schemaLocation="http://symfony.com/schema/dic/services
147-
http://symfony.com/schema/dic/services/services-1.0.xsd"
148-
>
149-
150-
<services>
151-
<service
152-
id="client_configuration"
153-
scope="client"
154-
synchronized="true"
155-
synthetic="true"
156-
class="AppBundle\Client\ClientConfiguration"
157-
/>
158-
</services>
159-
</container>
160-
161-
.. code-block:: php
162-
163-
// app/config/config.php
164-
use Symfony\Component\DependencyInjection\Definition;
165-
166-
$definition = new Definition(
167-
'AppBundle\Client\ClientConfiguration',
168-
array()
169-
);
170-
$definition->setScope('client');
171-
$definition->setSynchronized(true);
172-
$definition->setSynthetic(true);
173-
$container->setDefinition('client_configuration', $definition);
174-
175-
Now, if you inject this service using setter injection, there are no drawbacks
176-
and everything works without any special code in your service or in your definition::
177-
178-
// src/AppBundle/Mail/Mailer.php
179-
namespace AppBundle\Mail;
180-
181-
use AppBundle\Client\ClientConfiguration;
182-
183-
class Mailer
184-
{
185-
protected $clientConfiguration;
186-
187-
public function setClientConfiguration(ClientConfiguration $clientConfiguration = null)
188-
{
189-
$this->clientConfiguration = $clientConfiguration;
190-
}
191-
192-
public function sendEmail()
193-
{
194-
if (null === $this->clientConfiguration) {
195-
// throw an error?
196-
}
197-
198-
// ... do something using the client configuration here
199-
}
200-
}
201-
202-
Whenever the ``client`` scope is active, the service container will
203-
automatically call the ``setClientConfiguration()`` method when the
204-
``client_configuration`` service is set in the container.
205-
206-
You might have noticed that the ``setClientConfiguration()`` method accepts
207-
``null`` as a valid value for the ``client_configuration`` argument. That's
208-
because when leaving the ``client`` scope, the ``client_configuration`` instance
209-
can be ``null``. Of course, you should take care of this possibility in
210-
your code. This should also be taken into account when declaring your service:
211-
212-
.. configuration-block::
213-
214-
.. code-block:: yaml
215-
216-
# app/config/services.yml
217-
services:
218-
my_mailer:
219-
class: AppBundle\Mail\Mailer
220-
calls:
221-
- [setClientConfiguration, ["@?client_configuration="]]
222-
223-
.. code-block:: xml
224-
225-
<!-- app/config/services.xml -->
226-
<services>
227-
<service id="my_mailer"
228-
class="AppBundle\Mail\Mailer"
229-
>
230-
<call method="setClientConfiguration">
231-
<argument
232-
type="service"
233-
id="client_configuration"
234-
on-invalid="null"
235-
strict="false"
236-
/>
237-
</call>
238-
</service>
239-
</services>
240-
241-
.. code-block:: php
242-
243-
// app/config/services.php
244-
use Symfony\Component\DependencyInjection\Definition;
245-
use Symfony\Component\DependencyInjection\ContainerInterface;
115+
.. note::
246116

247-
$definition = $container->setDefinition(
248-
'my_mailer',
249-
new Definition('AppBundle\Mail\Mailer')
250-
)
251-
->addMethodCall('setClientConfiguration', array(
252-
new Reference(
253-
'client_configuration',
254-
ContainerInterface::NULL_ON_INVALID_REFERENCE,
255-
false
256-
)
257-
));
117+
Prior to Symfony 2.7, there was another alternative based on ``synchronized``
118+
services. However, these kind of services have been deprecated starting from
119+
Symfony 2.7.
258120

259121
.. _changing-service-scope:
260122

261-
B) Changing the Scope of your Service
123+
A) Changing the Scope of your Service
262124
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
263125

264126
Changing the scope of a service should be done in its definition. This example
@@ -302,7 +164,7 @@ argument is the ``ClientConfiguration`` object:
302164
303165
.. _passing-container:
304166

305-
C) Passing the Container as a Dependency of your Service
167+
B) Passing the Container as a Dependency of your Service
306168
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
307169

308170
Setting the scope to a narrower one is not always possible (for instance, a
@@ -338,7 +200,7 @@ into your service::
338200
in the first section (except that Symfony cannot detect that you are
339201
wrong).
340202

341-
The service config for this class would look something like this:
203+
The service configuration for this class would look something like this:
342204

343205
.. configuration-block::
344206

0 commit comments

Comments
 (0)