@@ -9,30 +9,33 @@ How to Create Service Aliases and Mark Services as Private
9
9
Marking Services as Public / Private
10
10
------------------------------------
11
11
12
- When defining services, you'll usually want to be able to access these definitions
13
- within your application code. These services are called *public *. For
14
- example, the ``doctrine `` service is a public service. This means that you can
15
- fetch it from the container using the ``get() `` method::
12
+ When defining a service, it can be made to be *public * or *private *. If a service
13
+ is *public *, it means that you can access it directly from the container at runtime.
14
+ For example, the ``doctrine `` service is a public service::
16
15
16
+ // only public services can be accessed in this way
17
17
$doctrine = $container->get('doctrine');
18
18
19
- In some cases, a service *only * exists to be injected into another service
20
- and is *not * intended to be fetched directly from the container as shown
21
- above.
19
+ But typically, services are accessed using :ref: `dependency injection <services-constructor-injection >`.
20
+ And in this case, those services do *not * need to be public.
22
21
23
22
.. _inlined-private-services :
24
23
25
- In these cases, to get a minor performance boost and ensure the service will not
26
- be retrieved directly from the container, you can set the service to be *not *
27
- public (i.e. private):
24
+ So unless you *specifically * need to access a service directly from the container
25
+ via ``$container->get() ``, the best-practice is to make your services *private *.
26
+ In fact, the :ref: `default services.yml configuration <container-public >` configures
27
+ all services to be private by default.
28
+
29
+ You can also control the ``public `` option on a service-by-service basis:
28
30
29
31
.. configuration-block ::
30
32
31
33
.. code-block :: yaml
32
34
33
35
services :
34
- foo :
35
- class : Example\Foo
36
+ # ...
37
+
38
+ AppBundle\Service\Foo :
36
39
public : false
37
40
38
41
.. code-block :: xml
@@ -43,29 +46,30 @@ public (i.e. private):
43
46
xsi : schemaLocation =" http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" >
44
47
45
48
<services >
46
- <service id =" foo " class = " Example \Foo" public =" false" />
49
+ <service id =" AppBundle\Service \Foo" public =" false" />
47
50
</services >
48
51
</container >
49
52
50
53
.. code-block :: php
51
54
52
- use Example \Foo;
55
+ use AppBundle\Service \Foo;
53
56
54
- $container->register('foo', Foo::class)
57
+ $container->register(Foo::class)
55
58
->setPublic(false);
56
59
57
- What makes private services special is that, since the container knows that the
58
- service will never be requested from outside, it can optimize whether and how it
59
- is instanciated. This increases the container's performance.
60
+ Private services are special because they allow the container to optimize whether
61
+ and how they are instantiated. This increases the container's performance.
60
62
61
63
Now that the service is private, you *should not * fetch the service directly
62
64
from the container::
63
65
64
- $container->get('foo');
66
+ use AppBundle\Service\Foo;
67
+
68
+ $container->get(Foo::class);
65
69
66
70
This *may or may not work *, depending on how the container has optimized the
67
- service instanciation and, even in the cases where it works, is
68
- deprecated. Simply said: A service can be marked as private if you do not want
71
+ service instantiation and, even in the cases where it works, is
72
+ deprecated. Simply said: A service should be marked as private if you do not want
69
73
to access it directly from your code.
70
74
71
75
However, if a service has been marked as private, you can still alias it
@@ -76,6 +80,8 @@ However, if a service has been marked as private, you can still alias it
76
80
Services are by default public, but it's considered a good practice to mark
77
81
as much services private as possible.
78
82
83
+ .. _services-alias :
84
+
79
85
Aliasing
80
86
--------
81
87
@@ -88,11 +94,13 @@ services.
88
94
.. code-block :: yaml
89
95
90
96
services :
91
- app.phpmailer :
92
- class : AppBundle\Mail\PhpMailer
97
+ # ...
98
+ AppBundle\Mail\PhpMailer :
99
+ public : false
93
100
94
101
app.mailer :
95
- alias : app.phpmailer
102
+ alias : AppBundle\Mail\PhpMailer
103
+ public : true
96
104
97
105
.. code-block :: xml
98
106
@@ -102,22 +110,23 @@ services.
102
110
xsi : schemaLocation =" http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" >
103
111
104
112
<services >
105
- <service id = " app.phpmailer " class =" AppBundle\Mail\PhpMailer" />
113
+ <service class =" AppBundle\Mail\PhpMailer" public = " false " />
106
114
107
- <service id =" app.mailer" alias =" app.phpmailer " />
115
+ <service id =" app.mailer" alias =" AppBundle\Mail\PhpMailer " />
108
116
</services >
109
117
</container >
110
118
111
119
.. code-block :: php
112
120
113
121
use AppBundle\Mail\PhpMailer;
114
122
115
- $container->register('app.phpmailer', PhpMailer::class);
123
+ $container->register(PhpMailer::class)
124
+ ->setPublic(false);
116
125
117
- $container->setAlias('app.mailer', 'app.phpmailer' );
126
+ $container->setAlias('app.mailer', PhpMailer::class );
118
127
119
128
This means that when using the container directly, you can access the
120
- ``app.phpmailer `` service by asking for the ``app.mailer `` service like this::
129
+ ``PhpMailer `` service by asking for the ``app.mailer `` service like this::
121
130
122
131
$container->get('app.mailer'); // Would return a PhpMailer instance
123
132
@@ -141,8 +150,7 @@ or you decided not to maintain it anymore), you can deprecate its definition:
141
150
142
151
.. code-block :: yaml
143
152
144
- acme.my_service :
145
- class : ...
153
+ AppBundle\Service\OldService :
146
154
deprecated : The "%service_id%" service is deprecated since 2.8 and will be removed in 3.0.
147
155
148
156
.. code-block :: xml
@@ -153,16 +161,18 @@ or you decided not to maintain it anymore), you can deprecate its definition:
153
161
xsi : schemaLocation =" http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" >
154
162
155
163
<services >
156
- <service id =" acme.my_service " class = " ... " >
164
+ <service id =" AppBundle\Service\OldService " >
157
165
<deprecated >The "%service_id%" service is deprecated since 2.8 and will be removed in 3.0.</deprecated >
158
166
</service >
159
167
</services >
160
168
</container >
161
169
162
170
.. code-block :: php
163
171
172
+ use AppBundle\Service\OldService;
173
+
164
174
$container
165
- ->register('acme.my_service', '...' )
175
+ ->register(OldService::class )
166
176
->setDeprecated(
167
177
true,
168
178
'The "%service_id%" service is deprecated since 2.8 and will be removed in 3.0.'
@@ -189,6 +199,6 @@ occurrence of the ``%service_id%`` placeholder in your template.
189
199
deprecated, until when it will be maintained and the alternative services
190
200
to use (if any).
191
201
192
- For service decorators (see above ), if the definition does not modify the
193
- deprecated status, it will inherit the status from the definition that is
194
- decorated.
202
+ For service decorators (see :doc: ` /service_container/service_decoration ` ), if the
203
+ definition does not modify the deprecated status, it will inherit the status from
204
+ the definition that is decorated.
0 commit comments