@@ -7,7 +7,7 @@ How to work with Scopes
7
7
This entry is all about scopes, a somewhat advanced topic related to the
8
8
:doc: `/book/service_container `. If you've ever gotten an error mentioning
9
9
"scopes" when creating services, or need to create a service that depends
10
- on the `request ` service, then this entry is for you.
10
+ on the `` request ` ` service, then this entry is for you.
11
11
12
12
Understanding Scopes
13
13
--------------------
@@ -16,49 +16,49 @@ The scope of a service controls how long an instance of a service is used
16
16
by the container. The Dependency Injection component provides two generic
17
17
scopes:
18
18
19
- - `container ` (the default one): The same instance is used each time you
19
+ - `` container ` ` (the default one): The same instance is used each time you
20
20
request it from this container.
21
21
22
- - `prototype `: A new instance is created each time you request the service.
22
+ - `` prototype ` `: A new instance is created each time you request the service.
23
23
24
- The FrameworkBundle also defines a third scope: `request `. This scope is
24
+ The FrameworkBundle also defines a third scope: `` request ` `. This scope is
25
25
tied to the request, meaning a new instance is created for each subrequest
26
26
and is unavailable outside the request (for instance in the CLI).
27
27
28
28
Scopes add a constraint on the dependencies of a service: a service cannot
29
29
depend on services from a narrower scope. For example, if you create a generic
30
- `my_foo ` service, but try to inject the `request ` component, you'll receive
30
+ `` my_foo `` service, but try to inject the `` request ` ` component, you'll receive
31
31
a :class: `Symfony\\ Component\\ DependencyInjection\\ Exception\\ ScopeWideningInjectionException `
32
32
when compiling the container. Read the sidebar below for more details.
33
33
34
34
.. sidebar :: Scopes and Dependencies
35
35
36
- Imagine you've configured a `my_mailer ` service. You haven't configured
37
- the scope of the service, so it defaults to `container `. In other words,
38
- every time you ask the container for the `my_mailer ` service, you get
36
+ Imagine you've configured a `` my_mailer ` ` service. You haven't configured
37
+ the scope of the service, so it defaults to `` container ` `. In other words,
38
+ every time you ask the container for the `` my_mailer ` ` service, you get
39
39
the same object back. This is usually how you want your services to work.
40
40
41
- Imagine, however, that you need the `request ` service in your `my_mailer `
41
+ Imagine, however, that you need the `` request `` service in your `` my_mailer ` `
42
42
service, maybe because you're reading the URL of the current request.
43
43
So, you add it as a constructor argument. Let's look at why this presents
44
44
a problem:
45
45
46
- * When requesting `my_mailer `, an instance of `my_mailer ` (let's call
47
- it *MailerA *) is created and the `request ` service (let's call it
46
+ * When requesting `` my_mailer `` , an instance of `` my_mailer ` ` (let's call
47
+ it *MailerA *) is created and the `` request ` ` service (let's call it
48
48
*RequestA *) is passed to it. Life is good!
49
49
50
50
* You've now made a subrequest in Symfony, which is a fancy way of saying
51
- that you've called, for example, the `{{ render(...) }} ` Twig function,
52
- which executes another controller. Internally, the old `request ` service
51
+ that you've called, for example, the `` {{ render(...) }} ` ` Twig function,
52
+ which executes another controller. Internally, the old `` request ` ` service
53
53
(*RequestA *) is actually replaced by a new request instance (*RequestB *).
54
54
This happens in the background, and it's totally normal.
55
55
56
- * In your embedded controller, you once again ask for the `my_mailer `
57
- service. Since your service is in the `container ` scope, the same
56
+ * In your embedded controller, you once again ask for the `` my_mailer ` `
57
+ service. Since your service is in the `` container ` ` scope, the same
58
58
instance (*MailerA *) is just re-used. But here's the problem: the
59
59
*MailerA * instance still contains the old *RequestA * object, which
60
60
is now **not ** the correct request object to have (*RequestB * is now
61
- the current `request ` service). This is subtle, but the mis-match could
61
+ the current `` request ` ` service). This is subtle, but the mis-match could
62
62
cause major problems, which is why it's not allowed.
63
63
64
64
So, that's the reason *why * scopes exist, and how they can cause
@@ -101,20 +101,20 @@ The scope of a service is set in the definition of the service:
101
101
new Definition('Acme\HelloBundle\Mail\GreetingCardManager')
102
102
)->setScope('request');
103
103
104
- If you don't specify the scope, it defaults to `container `, which is what
104
+ If you don't specify the scope, it defaults to `` container ` `, which is what
105
105
you want most of the time. Unless your service depends on another service
106
- that's scoped to a narrower scope (most commonly, the `request ` service),
106
+ that's scoped to a narrower scope (most commonly, the `` request ` ` service),
107
107
you probably don't need to set the scope.
108
108
109
109
Using a Service from a narrower Scope
110
110
-------------------------------------
111
111
112
112
If your service depends on a scoped service, the best solution is to put
113
113
it in the same scope (or a narrower one). Usually, this means putting your
114
- new service in the `request ` scope.
114
+ new service in the `` request ` ` scope.
115
115
116
116
But this is not always possible (for instance, a twig extension must be in
117
- the `container ` scope as the Twig environment needs it as a dependency).
117
+ the `` container ` ` scope as the Twig environment needs it as a dependency).
118
118
In these cases, you should pass the entire container into your service and
119
119
retrieve your dependency from the container each time you need it to be sure
120
120
you have the right instance::
0 commit comments