From 03956a8db79e835e3db43cac596cb0da154b2602 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 3 Jan 2020 17:33:12 +0100 Subject: [PATCH] [DependencyInjection] Reworded the article about factories --- service_container/factories.rst | 58 ++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/service_container/factories.rst b/service_container/factories.rst index 7abf0a93236..bc0f73b3475 100644 --- a/service_container/factories.rst +++ b/service_container/factories.rst @@ -4,13 +4,17 @@ Using a Factory to Create Services ================================== -Symfony's Service Container provides a powerful way of controlling the -creation of objects, allowing you to specify arguments passed to the constructor -as well as calling methods and setting parameters. Sometimes, however, this -will not provide you with everything you need to construct your objects. -For this situation, you can use a factory to create the object and tell -the service container to call a method on the factory rather than directly -instantiating the class. +Symfony's Service Container provides multiple features to control the creation +of objects, allowing you to specify arguments passed to the constructor as well +as calling methods and setting parameters. + +However, sometimes you need to apply the `factory design pattern`_ to delegate +the object creation to some special object called "the factory". In those cases, +the service container can call a method on your factory to create the object +rather than directly instantiating the class. + +Static Factories +---------------- Suppose you have a factory that configures and returns a new ``NewsletterManager`` object by calling the static ``createNewsletterManager()`` method:: @@ -27,9 +31,9 @@ object by calling the static ``createNewsletterManager()`` method:: } } -To make the ``NewsletterManager`` object available as a service, you can -configure the service container to use the -``NewsletterManagerStaticFactory::createNewsletterManager()`` factory method: +To make the ``NewsletterManager`` object available as a service, use the +``factory`` option to define which method of which class must be called to +create its object: .. configuration-block:: @@ -40,7 +44,7 @@ configure the service container to use the # ... App\Email\NewsletterManager: - # call the static method + # the first argument is the class and the second argument is the static method factory: ['App\Email\NewsletterManagerStaticFactory', 'createNewsletterManager'] .. code-block:: xml @@ -54,7 +58,7 @@ configure the service container to use the - + + - @@ -144,15 +152,20 @@ Configuration of the service container then looks like this: return function(ContainerConfigurator $configurator) { $services = $configurator->services(); + // first, create a service for the factory $services->set(NewsletterManagerFactory::class); - // call a method on the specified factory service + // second, use the factory service as the first argument of the 'factory' + // method and the factory method as the second argument $services->set(NewsletterManager::class) ->factory([ref(NewsletterManagerFactory::class), 'createNewsletterManager']); }; .. _factories-invokable: +Invokable Factories +------------------- + Suppose you now change your factory method to ``__invoke()`` so that your factory service can be used as a callback:: @@ -234,8 +247,8 @@ Passing Arguments to the Factory Method that's enabled for your service. If you need to pass arguments to the factory method you can use the ``arguments`` -options. For example, suppose the ``createNewsletterManager()`` method in the previous -example takes the ``templating`` service as an argument: +option. For example, suppose the ``createNewsletterManager()`` method in the +previous examples takes the ``templating`` service as an argument: .. configuration-block:: @@ -285,3 +298,4 @@ example takes the ``templating`` service as an argument: ; }; +.. _`factory design pattern`: https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)