Skip to content

Commit cb07e30

Browse files
committed
Add "Handling decorations on non existent service"
1 parent 07fd43a commit cb07e30

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

service_container/service_decoration.rst

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,115 @@ The generated code will be the following::
313313

314314
$this->services[Foo::class] = new Baz(new Bar(new Foo()));
315315

316+
Control the Behavior When the Decorated Service Does Not Exist
317+
--------------------------------------------------------------
318+
319+
.. versionadded:: 4.4
320+
321+
The ``decoration_on_invalid`` option has been introduced in Symfony 4.4.
322+
In previous versions, a ``ServiceNotFoundException`` was always thrown.
323+
324+
When you decorate a service that doesn't exist, the ``decoration_on_invalid``
325+
option allows you to choose the behavior to adopt.
326+
327+
Three different behaviors are available:
328+
329+
* ``exception``: A ``ServiceNotFoundException`` will be thrown telling that decorator's dependency is missing. (default)
330+
* ``ignore``: The container will remove the decorator.
331+
* ``null``: The container will keep the decorator service and will set the decorated one to ``null``.
332+
333+
.. configuration-block::
334+
335+
.. code-block:: yaml
336+
337+
# config/services.yaml
338+
Foo: ~
339+
340+
Bar:
341+
decorates: Foo
342+
decoration_on_invalid: ignore
343+
arguments: ['@Bar.inner']
344+
345+
.. code-block:: xml
346+
347+
<!-- config/services.xml -->
348+
<?xml version="1.0" encoding="UTF-8" ?>
349+
350+
<container xmlns="http://symfony.com/schema/dic/services"
351+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
352+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
353+
354+
<services>
355+
<service id="Foo"/>
356+
357+
<service id="Bar" decorates="Foo" decoration-on-invalid="ignore">
358+
<argument type="service" id="Bar.inner"/>
359+
</service>
360+
</services>
361+
</container>
362+
363+
.. code-block:: php
364+
365+
// config/services.php
366+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
367+
368+
use Symfony\Component\DependencyInjection\ContainerInterface;
369+
370+
return function(ContainerConfigurator $configurator) {
371+
$services = $configurator->services();
372+
373+
$services->set(Foo::class);
374+
375+
$services->set(Bar::class)
376+
->decorate(Foo::class, null, 0, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)
377+
->args([ref(Bar::class.'.inner')])
378+
;
379+
};
380+
381+
.. caution::
382+
383+
When using ``null``, you may have to update the decorator constructor in
384+
order to make decorated dependency nullable.
385+
386+
.. configuration-block::
387+
388+
.. code-block:: yaml
389+
390+
App\Service\DecoratorService:
391+
decorates: Acme\OptionalBundle\Service\OptionalService
392+
decoration_on_invalid: null
393+
arguments: ['@App\Service\DecoratorService.inner']
394+
395+
.. code-block:: php
396+
397+
namespace App\Service;
398+
399+
use Acme\OptionalBundle\Service\OptionalService;
400+
401+
class DecoratorService
402+
{
403+
private $decorated;
404+
405+
public function __construct(?OptionalService $decorated)
406+
{
407+
$this->decorated = $decorated;
408+
}
409+
410+
public function tellInterestingStuff(): string
411+
{
412+
if (!$this->decorated) {
413+
return 'Just one interesting thing';
414+
}
415+
416+
return $this->decorated->tellInterestingStuff().' + one more interesting thing';
417+
}
418+
}
419+
420+
.. note::
421+
422+
Sometimes, you may want to add a compiler pass that creates service
423+
definitions on the fly. If you want to decorate such a service,
424+
be sure that your compiler pass is registered with ``PassConfig::TYPE_BEFORE_OPTIMIZATION``
425+
type so that the decoration pass will be able to find the created services.
426+
316427
.. _`Decorator pattern`: https://en.wikipedia.org/wiki/Decorator_pattern

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy