From 54fe3d90865a680c0cf874b7cc5819b49721823a Mon Sep 17 00:00:00 2001 From: Harm van Tilborg Date: Tue, 17 Jan 2017 12:33:45 +0100 Subject: [PATCH] More clear description of factory service creation --- service_container/factories.rst | 105 ++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 27 deletions(-) diff --git a/service_container/factories.rst b/service_container/factories.rst index 624f0b167cf..f7b306af4d7 100644 --- a/service_container/factories.rst +++ b/service_container/factories.rst @@ -13,9 +13,9 @@ the service container to call a method on the factory rather than directly instantiating the class. Suppose you have a factory that configures and returns a new ``NewsletterManager`` -object:: +object by calling the static ``createNewsletterManager()`` method:: - class NewsletterManagerFactory + class NewsletterManagerStaticFactory { public static function createNewsletterManager() { @@ -29,45 +29,98 @@ object:: To make the ``NewsletterManager`` object available as a service, you can configure the service container to use the -``NewsletterManagerFactory::createNewsletterManager()`` factory method: +``NewsletterManagerStaticFactory::createNewsletterManager()`` factory method: .. configuration-block:: .. code-block:: yaml + # app/config/services.yml + services: app.newsletter_manager: class: AppBundle\Email\NewsletterManager - # call a static method - factory: ['AppBundle\Email\NewsletterManager', create] + # call the static method + factory: ['AppBundle\Email\NewsletterManagerStaticFactory', createNewsletterManager] + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // app/config/services.php + + use AppBundle\Email\NewsletterManager; + use AppBundle\Email\NewsletterManagerStaticFactory; + use Symfony\Component\DependencyInjection\Definition; + // ... + + $definition = new Definition(NewsletterManager::class); + // call the static method + $definition->setFactory(array(NewsletterManagerStaticFactory::class, 'createNewsletterManager')); + + $container->setDefinition('app.newsletter_manager', $definition); + +.. note:: + + When using a factory to create services, the value chosen for the ``class`` + option has no effect on the resulting service. The actual class name + only depends on the object that is returned by the factory. However, + the configured class name may be used by compiler passes and therefore + should be set to a sensible value. + +If your factory is not using a static function to configure and create your +service, but a regular method, you can instantiate the factory itself as a +service too. Later, in the ":ref:`factories-passing-arguments-factory-method`" +section, you learn how you can inject arguments in this method. + +Configuration of the service container then looks like this: + +.. configuration-block:: + + .. code-block:: yaml + # app/config/services.yml + + services: app.newsletter_manager_factory: class: AppBundle\Email\NewsletterManagerFactory app.newsletter_manager: class: AppBundle\Email\NewsletterManager - # call a method on the specified service + # call a method on the specified factory service factory: 'app.newsletter_manager_factory:createNewsletterManager' .. code-block:: xml + + - - - - - - + @@ -77,22 +130,18 @@ configure the service container to use the .. code-block:: php + // app/config/services.php + use AppBundle\Email\NewsletterManager; use AppBundle\Email\NewsletterManagerFactory; use Symfony\Component\DependencyInjection\Definition; // ... - $definition = new Definition(NewsletterManager::class); - // call a static method - $definition->setFactory(array(NewsletterManager::class, 'create')); - - $container->setDefinition('app.newsletter_manager', $definition); - $container->register('app.newsletter_manager_factory', NewsletterManagerFactory::class); $newsletterManager = new Definition(NewsletterManager::class); - // call a method on the specified service + // call a method on the specified factory service $newsletterManager->setFactory(array( new Reference('app.newsletter_manager_factory'), 'createNewsletterManager' @@ -100,14 +149,6 @@ configure the service container to use the $container->setDefinition('app.newsletter_manager', $newsletterManager); -.. note:: - - When using a factory to create services, the value chosen for the ``class`` - option has no effect on the resulting service. The actual class name - only depends on the object that is returned by the factory. However, - the configured class name may be used by compiler passes and therefore - should be set to a sensible value. - .. note:: The traditional configuration syntax in YAML files used an array to define @@ -115,12 +156,16 @@ configure the service container to use the .. code-block:: yaml + # app/config/services.yml + app.newsletter_manager: # new syntax factory: 'app.newsletter_manager_factory:createNewsletterManager' # old syntax factory: ['@app.newsletter_manager_factory', createNewsletterManager] +.. _factories-passing-arguments-factory-method: + Passing Arguments to the Factory Method --------------------------------------- @@ -132,6 +177,8 @@ method in the previous example takes the ``templating`` service as an argument: .. code-block:: yaml + # app/config/services.yml + services: # ... @@ -142,6 +189,8 @@ method in the previous example takes the ``templating`` service as an argument: .. code-block:: xml + +