@@ -185,3 +185,95 @@ the service itself gets loaded. To do so, you can use the ``file`` directive.
185185
186186 Notice that Symfony will internally call the PHP statement ``require_once ``,
187187which 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