From d7998b06a726be482bf450ac051a0eceb90d73d1 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Wed, 19 Nov 2014 19:34:01 +0100 Subject: [PATCH] Use new factory syntax --- components/dependency_injection/factories.rst | 156 ++++++------------ 1 file changed, 52 insertions(+), 104 deletions(-) diff --git a/components/dependency_injection/factories.rst b/components/dependency_injection/factories.rst index 9f74efa50d5..7fe20414661 100644 --- a/components/dependency_injection/factories.rst +++ b/components/dependency_injection/factories.rst @@ -4,6 +4,10 @@ Using a Factory to Create Services ================================== +.. versionadded:: 2.6 + The new ``setFactory`` method was introduced in Symfony 2.6. Refer to older + versions for the syntax for factories prior to 2.6. + 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 @@ -15,9 +19,9 @@ the class. Suppose you have a factory that configures and returns a new ``NewsletterManager`` object:: - class NewsletterFactory + class NewsletterManagerFactory { - public function get() + public static function createNewsletterManager() { $newsletterManager = new NewsletterManager(); @@ -28,22 +32,17 @@ object:: } To make the ``NewsletterManager`` object available as a service, you can -configure the service container to use the ``NewsletterFactory`` factory -class: +configure the service container to use the +``NewsletterFactory::createNewsletterManager()`` factory method: .. configuration-block:: .. code-block:: yaml - parameters: - # ... - newsletter_manager.class: NewsletterManager - newsletter_factory.class: NewsletterFactory services: newsletter_manager: - class: "%newsletter_manager.class%" - factory_class: "%newsletter_factory.class%" - factory_method: get + class: NewsletterManager + factory: [NewsletterManagerFactory, createNewsletterManager] .. code-block:: xml @@ -52,18 +51,10 @@ class: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - NewsletterManager - NewsletterFactory - - - + + + @@ -72,35 +63,26 @@ class: use Symfony\Component\DependencyInjection\Definition; // ... - $container->setParameter('newsletter_manager.class', 'NewsletterManager'); - $container->setParameter('newsletter_factory.class', 'NewsletterFactory'); - - $definition = new Definition('%newsletter_manager.class%'); - $definition->setFactoryClass('%newsletter_factory.class%'); - $definition->setFactoryMethod('get'); + $definition = new Definition('NewsletterManager'); + $definition->setFactory(array('NewsletterManagerFactory', 'createNewsletterManager')); $container->setDefinition('newsletter_manager', $definition); -When you specify the class to use for the factory (via ``factory_class``) -the method will be called statically. If the factory itself should be instantiated -and the resulting object's method called, configure the factory itself as a service. -In this case, the method (e.g. get) should be changed to be non-static: +Now, the method will be called statically. If the factory class itself should +be instantiated and the resulting object's method called, configure the factory +itself as a service. In this case, the method (e.g. get) should be changed to +be non-static. .. configuration-block:: .. code-block:: yaml - parameters: - # ... - newsletter_manager.class: NewsletterManager - newsletter_factory.class: NewsletterFactory services: - newsletter_factory: - class: "%newsletter_factory.class%" + newsletter_manager.factory: + class: NewsletterManagerFactory newsletter_manager: - class: "%newsletter_manager.class%" - factory_service: newsletter_factory - factory_method: get + class: NewsletterManager + factory: ["@newsletter_manager.factory", createNewsletterManager] .. code-block:: xml @@ -109,47 +91,29 @@ In this case, the method (e.g. get) should be changed to be non-static: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - NewsletterManager - NewsletterFactory - - - + - + + + .. code-block:: php + use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Definition; // ... - $container->setParameter('newsletter_manager.class', 'NewsletterManager'); - $container->setParameter('newsletter_factory.class', 'NewsletterFactory'); + $container->register('newsletter_manager.factory', 'createNewsletterManager'); - $container->setDefinition('newsletter_factory', new Definition( - '%newsletter_factory.class%' + $newsletterManager = new Definition(); + $newsletterManager->setFactory(array( + new Reference('newsletter_manager.factory'), + 'createNewsletterManager' )); - $container->setDefinition('newsletter_manager', new Definition( - '%newsletter_manager.class%' - ))->setFactoryService( - 'newsletter_factory' - )->setFactoryMethod( - 'get' - ); - -.. note:: - - The factory service is specified by its id name and not a reference to - the service itself. So, you do not need to use the @ syntax for this in - YAML configurations. + $container->setDefinition('newsletter_manager', $newsletterManager); Passing Arguments to the Factory Method --------------------------------------- @@ -162,17 +126,13 @@ in the previous example takes the ``templating`` service as an argument: .. code-block:: yaml - parameters: - # ... - newsletter_manager.class: NewsletterManager - newsletter_factory.class: NewsletterFactory services: - newsletter_factory: - class: "%newsletter_factory.class%" + newsletter_manager.factory: + class: NewsletterManagerFactory + newsletter_manager: - class: "%newsletter_manager.class%" - factory_service: newsletter_factory - factory_method: get + class: NewsletterManager + factory: ["@newsletter_manager.factory", createNewsletterManager] arguments: - "@templating" @@ -183,42 +143,30 @@ in the previous example takes the ``templating`` service as an argument: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - NewsletterManager - NewsletterFactory - - - + - - - + + + .. code-block:: php + use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Definition; // ... - $container->setParameter('newsletter_manager.class', 'NewsletterManager'); - $container->setParameter('newsletter_factory.class', 'NewsletterFactory'); + $container->register('newsletter_manager.factory', 'NewsletterManagerFactory'); - $container->setDefinition('newsletter_factory', new Definition( - '%newsletter_factory.class%' - )); - $container->setDefinition('newsletter_manager', new Definition( - '%newsletter_manager.class%', + $newsletterManager = new Definition( + 'NewsletterManager', array(new Reference('templating')) - ))->setFactoryService( - 'newsletter_factory' - )->setFactoryMethod( - 'get' ); + $newsletterManager->setFactory(array( + new Reference('newsletter_manager.factory'), + 'createNewsletterManager' + )); + $container->setDefinition('newsletter_manager', $newsletterManager);