@@ -185,3 +185,95 @@ the service itself gets loaded. To do so, you can use the ``file`` directive.
185
185
186
186
Notice that Symfony will internally call the PHP statement ``require_once ``,
187
187
which means that your file will be included only once per request.
188
+
189
+ Decorating Services
190
+ -------------------
191
+
192
+ .. versionadded :: 2.5
193
+ Decorated services were introduced in Symfony 2.5.
194
+
195
+ When overriding an existing definition, the old service is lost:
196
+
197
+ .. code-block :: php
198
+
199
+ $container->register('foo', 'FooService');
200
+
201
+ // this is going to replace the old definition with the new one
202
+ // old definition is lost
203
+ $container->register('foo', 'CustomFooService');
204
+
205
+ Most of the time, that's exactly what you want to do. But sometimes,
206
+ you might want to decorate the old one instead. In this case, the
207
+ old service should be kept around to be able to reference it in the
208
+ new one. This configuration replaces ``foo `` with a new one, but keeps
209
+ a reference of the old one as ``bar.inner ``:
210
+
211
+ .. configuration-block ::
212
+
213
+ .. code-block :: yaml
214
+
215
+ bar :
216
+ public : false
217
+ class : stdClass
218
+ decorates : foo
219
+ arguments : ["@bar.inner"]
220
+
221
+ .. code-block :: xml
222
+
223
+ <service id =" bar" class =" stdClass" decorates =" foo" public =" false" >
224
+ <argument type =" service" id =" bar.inner" />
225
+ </service >
226
+
227
+ .. code-block :: php
228
+
229
+ use Symfony\Component\DependencyInjection\Reference;
230
+
231
+ $container->register('bar', 'stdClass')
232
+ ->addArgument(new Reference('bar.inner'))
233
+ ->setPublic(false)
234
+ ->setDecoratedService('foo');
235
+
236
+ Here is what's going on here: the ``setDecoratedService()` method tells
237
+ the container that the ``bar `` service should replace the ``foo `` service,
238
+ renaming ``foo `` to ``bar.inner ``.
239
+ By convention, the old ``foo `` service is going to be renamed ``bar.inner ``,
240
+ so you can inject it into your new service.
241
+
242
+ .. note ::
243
+ The generated inner id is based on the id of the decorator service
244
+ (``bar `` here), not of the decorated service (``foo `` here). This is
245
+ mandatory to allow several decorators on the same service (they need to have
246
+ different generated inner ids).
247
+
248
+ Most of the time, the decorator should be declared private, as you will not
249
+ need to retrieve it as ``bar `` from the container. The visibility of the
250
+ decorated ``foo `` service (which is an alias for ``bar ``) will still be the
251
+ same as the original ``foo `` visibility.
252
+
253
+ You can change the inner service name if you want to:
254
+
255
+ .. configuration-block ::
256
+
257
+ .. code-block :: yaml
258
+
259
+ bar :
260
+ class : stdClass
261
+ public : false
262
+ decorates : foo
263
+ decoration_inner_name : bar.wooz
264
+ arguments : ["@bar.wooz"]
265
+
266
+ .. code-block :: xml
267
+
268
+ <service id =" bar" class =" stdClass" decorates =" foo" decoration-inner-name =" bar.wooz" public =" false" >
269
+ <argument type =" service" id =" bar.wooz" />
270
+ </service >
271
+
272
+ .. code-block :: php
273
+
274
+ use Symfony\Component\DependencyInjection\Reference;
275
+
276
+ $container->register('bar', 'stdClass')
277
+ ->addArgument(new Reference('bar.wooz'))
278
+ ->setPublic(false)
279
+ ->setDecoratedService('foo', 'bar.wooz');
0 commit comments