Skip to content

Commit c35e9f5

Browse files
committed
minor #17105 [DependencyInjection] Document proxifying interfaces for lazy services (tucksaun)
This PR was merged into the 4.4 branch. Discussion ---------- [DependencyInjection] Document proxifying interfaces for lazy services Symfony 4.2 introduced the possibility of lazy load services using final classes by proxyfying specific interfaces (symfony/symfony#20656), but this has not been documented yet. Targeting 4.4 because 4.4 is the oldest maintained branch, but should I target 4.2 as this was introduced in 4.2? Fix #10295 Commits ------- f86b976 [DI] Document proxifying interfaces for lazy services
2 parents f438259 + f86b976 commit c35e9f5

File tree

1 file changed

+77
-1
lines changed

1 file changed

+77
-1
lines changed

service_container/lazy_services.rst

+77-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ until you interact with the proxy in some way.
2525

2626
.. caution::
2727

28-
Lazy services do not support `final`_ classes.
28+
Lazy services do not support `final`_ classes. You can use `Interface
29+
Proxifying`_ to work around this limitation.
2930

3031
In PHP versions prior to 8.0 lazy services do not support parameters with
3132
default values for built-in PHP classes (e.g. ``PDO``).
@@ -100,6 +101,81 @@ To check if your proxy works you can check the interface of the received object:
100101
over the ``lazy`` flag and directly instantiate the service as it would
101102
normally do.
102103

104+
Interface Proxifying
105+
--------------------
106+
107+
Under the hood, proxies generated to lazily load services inherit from the class
108+
used by the service. But sometimes this is not possible at all (`final`_ classes
109+
can not be extended for example) or not convenient.
110+
111+
To workaround this limitation, you can configure a proxy to only implements
112+
specific interfaces.
113+
114+
.. versionadded:: 4.2
115+
116+
Proxyfying interfaces was introduced in Symfony 4.2.
117+
118+
.. configuration-block::
119+
120+
.. code-block:: yaml
121+
122+
# config/services.yaml
123+
services:
124+
App\Twig\AppExtension:
125+
lazy: 'Twig\Extension\ExtensionInterface'
126+
# or a complete definition:
127+
lazy: true
128+
tags:
129+
- { name: 'proxy', interface: 'Twig\Extension\ExtensionInterface' }
130+
131+
.. code-block:: xml
132+
133+
<!-- config/services.xml -->
134+
<?xml version="1.0" encoding="UTF-8" ?>
135+
<container xmlns="http://symfony.com/schema/dic/services"
136+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
137+
xsi:schemaLocation="http://symfony.com/schema/dic/services
138+
https://symfony.com/schema/dic/services/services-1.0.xsd">
139+
140+
<services>
141+
<service id="App\Twig\AppExtension" lazy="Twig\Extension\ExtensionInterface"/>
142+
<!-- or a complete definition: -->
143+
<service id="App\Twig\AppExtension" lazy="true">
144+
<tag name="proxy" interface="Twig\Extension\ExtensionInterface"/>
145+
</service>
146+
</services>
147+
</container>
148+
149+
.. code-block:: php
150+
151+
// config/services.php
152+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
153+
154+
use App\Twig\AppExtension;
155+
use Twig\Extension\ExtensionInterface;
156+
157+
return function(ContainerConfigurator $configurator) {
158+
$services = $configurator->services();
159+
160+
$services->set(AppExtension::class)
161+
->lazy()
162+
->tag('proxy', ['interface' => ExtensionInterface::class])
163+
;
164+
};
165+
166+
The virtual `proxy`_ injected into other services will only implement the
167+
specified interfaces and will not extend the original service class allowing to
168+
lazy load service using `final`_ classes. You can configure the proxy to
169+
implement multiple interfaces by repeating the "proxy" tag.
170+
171+
.. tip::
172+
173+
This features can also act as a "safe guard". Because the proxy does not
174+
extends the original class, only the methods defined by the interfaces can
175+
be called, preventing to call implementation specific one. It also prevents
176+
injecting the dependency at all if you type hinted a concrete implementation
177+
instead of the interface.
178+
103179
Additional Resources
104180
--------------------
105181

0 commit comments

Comments
 (0)