Skip to content

Commit b1074ab

Browse files
committed
[DependencyInjection] Invokable Factory Services
Document new invokable factories (and configurators) implemented in symfony/symfony#30255.
1 parent c63bd46 commit b1074ab

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

service_container/configurators.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,74 @@ the service id and the method name:
195195
# old syntax
196196
configurator: ['@App\Mail\EmailConfigurator', configure]
197197
198+
.. _configurators-invokable:
199+
200+
Starting from Symfony 4.3 services can be configured via invokable configurators
201+
(replacing the ``configure()`` method with ``__invoke()``) by omitting the
202+
method name, just as route definitions can reference :ref:`invokable
203+
controllers <controller-service-invoke>`.
204+
205+
.. code-block:: yaml
206+
207+
# app/config/services.yml
208+
services:
209+
# ...
210+
211+
# Registers all 4 classes as services, including AppBundle\Mail\EmailConfigurator
212+
AppBundle\:
213+
resource: '../../src/AppBundle/*'
214+
# ...
215+
216+
# override the services to set the configurator
217+
AppBundle\Mail\NewsletterManager:
218+
configurator: '@AppBundle\Mail\EmailConfigurator'
219+
220+
AppBundle\Mail\GreetingCardManager:
221+
configurator: '@AppBundle\Mail\EmailConfigurator'
222+
223+
.. code-block:: xml
224+
225+
<!-- app/config/services.xml -->
226+
<?xml version="1.0" encoding="UTF-8" ?>
227+
<container xmlns="http://symfony.com/schema/dic/services"
228+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
229+
xsi:schemaLocation="http://symfony.com/schema/dic/services
230+
http://symfony.com/schema/dic/services/services-1.0.xsd">
231+
232+
<services>
233+
<prototype namespace="AppBundle\" resource="../../src/AppBundle/*" />
234+
235+
<service id="AppBundle\Mail\NewsletterManager">
236+
<configurator service="AppBundle\Mail\EmailConfigurator" />
237+
</service>
238+
239+
<service id="AppBundle\Mail\GreetingCardManager">
240+
<configurator service="AppBundle\Mail\EmailConfigurator" />
241+
</service>
242+
</services>
243+
</container>
244+
245+
.. code-block:: php
246+
247+
// app/config/services.php
248+
use AppBundle\Mail\GreetingCardManager;
249+
use AppBundle\Mail\NewsletterManager;
250+
use Symfony\Component\DependencyInjection\Definition;
251+
use Symfony\Component\DependencyInjection\Reference;
252+
253+
// Same as before
254+
$definition = new Definition();
255+
256+
$definition->setAutowired(true);
257+
258+
$this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*');
259+
260+
$container->getDefinition(NewsletterManager::class)
261+
->setConfigurator(new Reference(EmailConfigurator::class));
262+
263+
$container->getDefinition(GreetingCardManager::class)
264+
->setConfigurator(new Reference(EmailConfigurator::class));
265+
198266
That's it! When requesting the ``App\Mail\NewsletterManager`` or
199267
``App\Mail\GreetingCardManager`` service, the created instance will first be
200268
passed to the ``EmailConfigurator::configure()`` method.

service_container/factories.rst

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,72 @@ Configuration of the service container then looks like this:
157157
# old syntax
158158
factory: ['@App\Email\NewsletterManagerFactory', createNewsletterManager]
159159
160+
.. _factories-invokable:
161+
162+
Suppose you now change your factory method to ``__invoke()`` so that your
163+
factory service can be used as a callback::
164+
165+
class InvokableNewsletterManagerFactory
166+
{
167+
public function __invoke()
168+
{
169+
$newsletterManager = new NewsletterManager();
170+
171+
// ...
172+
173+
return $newsletterManager;
174+
}
175+
}
176+
177+
Starting from Symfony 4.3 services can be created and configured via invokable
178+
factory services by omitting the method name, just as route definitions can
179+
reference :ref:`invokable controllers <controller-service-invoke>`.
180+
181+
.. configuration-block::
182+
183+
.. code-block:: yaml
184+
185+
# app/config/services.yml
186+
187+
services:
188+
# ...
189+
190+
AppBundle\Email\NewsletterManager:
191+
class: AppBundle\Email\NewsletterManager
192+
factory: '@AppBundle\Email\NewsletterManagerFactory'
193+
194+
.. code-block:: xml
195+
196+
<!-- app/config/services.xml -->
197+
198+
<?xml version="1.0" encoding="UTF-8" ?>
199+
<container xmlns="http://symfony.com/schema/dic/services"
200+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
201+
xsi:schemaLocation="http://symfony.com/schema/dic/services
202+
http://symfony.com/schema/dic/services/services-1.0.xsd">
203+
204+
<services>
205+
<!-- ... -->
206+
207+
<service id="AppBundle\Email\NewsletterManager"
208+
class="AppBundle\Email\NewsletterManager">
209+
<factory service="AppBundle\Email\NewsletterManagerFactory" />
210+
</service>
211+
</services>
212+
</container>
213+
214+
.. code-block:: php
215+
216+
// app/config/services.php
217+
218+
use AppBundle\Email\NewsletterManager;
219+
use AppBundle\Email\NewsletterManagerFactory;
220+
use Symfony\Component\DependencyInjection\Reference;
221+
222+
// ...
223+
$container->register(NewsletterManager::class, NewsletterManager::class)
224+
->setFactory(new Reference(NewsletterManagerFactory::class));
225+
160226
.. _factories-passing-arguments-factory-method:
161227

162228
Passing Arguments to the Factory Method

0 commit comments

Comments
 (0)