From d00a3c8740f97541d6129d752fa42f72c5905bf0 Mon Sep 17 00:00:00 2001 From: HeahDude Date: Thu, 27 Jul 2017 14:15:49 +0200 Subject: [PATCH 1/2] Fixed usage of default configuration in PHP --- service_container.rst | 56 ++++++++++++++++++++++++---- service_container/3.3-di-changes.rst | 54 +++++++++++++++++++-------- service_container/configurators.rst | 16 ++++---- 3 files changed, 96 insertions(+), 30 deletions(-) diff --git a/service_container.rst b/service_container.rst index 90e642d6a97..137914dcd64 100644 --- a/service_container.rst +++ b/service_container.rst @@ -215,13 +215,19 @@ each time you ask for it. .. code-block:: php // app/config/services.php - // _defaults and loading entire directories is not possible with PHP configuration - // you need to define your services one-by-one - use AppBundle\Service\MessageGenerator; + use Symfony\Component\DependencyInjection\Definition; - $container->autowire(MessageGenerator::class) + // To use as default template + $definition = new Definition(); + + $definition + ->setAutowired(true) ->setAutoconfigured(true) - ->setPublic(false); + ->setPublic(false) + ; + + // $this is a reference to the current loader + $this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*', '../../src/AppBundle/{Entity,Repository}'); Thanks to this configuration, you can automatically use any classes from the ``src/AppBundle`` directory as a service, without needing to manually configure @@ -475,12 +481,21 @@ pass here. No problem! In your configuration, you can explicitly set this argume // app/config/services.php use AppBundle\Updates\SiteUpdateManager; + use Symfony\Component\DependencyInjection\Definition; - // _defaults and importing directories does not work in PHP - // but registering a service explicitly does - $container->autowire(SiteUpdateManager::class) + // Same as before + $definition = new Definition(); + + $definition + ->setAutowired(true) ->setAutoconfigured(true) ->setPublic(false) + ; + + $this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*', '../../src/AppBundle/{Entity,Repository}'); + + // Explicitly configure the service + $container->getDefinition(SiteUpdateManager::class) ->setArgument('$adminEmail', 'manager@example.com'); .. versionadded:: 3.3 @@ -860,6 +875,31 @@ key. For example, the default Symfony configuration contains this: + .. code-block:: php + + // app/config/services.php + use Symfony\Component\DependencyInjection\Definition; + + // To use as default template + $definition = new Definition(); + + $definition + ->setAutowired(true) + ->setAutoconfigured(true) + ->setPublic(false) + ; + + $this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*', '../../src/AppBundle/{Entity,Repository}'); + + // Changes default config + $definition + ->setPublic(true) + ->addTag('controller.service_arguments') + ; + + // $this is a reference to the current loader + $this->registerClasses($definition, 'AppBundle\\Controller\\', '../../src/AppBundle/Controller/*'); + This can be used to quickly make many classes available as services and apply some default configuration. The ``id`` of each service is its fully-qualified class name. You can override any service that's imported by using its id (class name) below diff --git a/service_container/3.3-di-changes.rst b/service_container/3.3-di-changes.rst index c9c9580cc54..597847a2504 100644 --- a/service_container/3.3-di-changes.rst +++ b/service_container/3.3-di-changes.rst @@ -81,21 +81,37 @@ Symfony Standard Edition: + + .. code-block:: php // app/config/services.php + use Symfony\Component\DependencyInjection\Definition; - // _defaults and loading entire directories is not possible with PHP configuration - // you need to define your services one-by-one - use AppBundle\Controller\DefaultController; + // To use as default template + $definition = new Definition(); - $container->autowire(DefaultController::class) + $definition + ->setAutowired(true) ->setAutoconfigured(true) + ->setPublic(false) + ; + + $this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*', '../../src/AppBundle/{Entity,Repository}'); + + // Changes default config + $definition + ->setPublic(true) ->addTag('controller.service_arguments') - ->setPublic(true); + ; + + // $this is a reference to the current loader + $this->registerClasses($definition, 'AppBundle\\Controller\\', '../../src/AppBundle/Controller/*'); + + // add more services, or override services that need manual wiring This small bit of configuration contains a paradigm shift of how services are configured in Symfony. @@ -147,9 +163,18 @@ thanks to the following config: .. code-block:: php // app/config/services.php + use Symfony\Component\DependencyInjection\Definition; - // services cannot be automatically loaded with PHP configuration - // you need to define your services one-by-one + // To use as default template + $definition = new Definition(); + + $definition + ->setAutowired(true) + ->setAutoconfigured(true) + ->setPublic(false) + ; + + $this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*', '../../src/AppBundle/{Entity,Repository}'); This means that every class in ``src/AppBundle/`` is *available* to be used as a service. And thanks to the ``_defaults`` section at the top of the file, all of @@ -347,15 +372,14 @@ The third big change is that, in a new Symfony 3.3 project, your controllers are .. code-block:: php // app/config/services.php + use Symfony\Component\DependencyInjection\Definition; - // loading entire directories is not possible with PHP configuration - // you need to define your services one-by-one - use AppBundle\Controller\DefaultController; + // To use as default template + $definition = new Definition(); - $container->autowire(DefaultController::class) - ->setAutoconfigured(true) - ->addTag('controller.service_arguments') - ->setPublic(true); + $definition->setPublic(true); + + $this->registerClasses($definition, 'AppBundle\\Controller\\', '../../src/AppBundle/Controller/*'); But, you might not even notice this. First, your controllers *can* still extend the same base ``Controller`` class or a new :ref:`AbstractController `. @@ -642,7 +666,7 @@ You're now ready to automatically register all services in ``src/AppBundle/`` + AppBundle\: + resource: '../../src/AppBundle/*' + exclude: '../../src/AppBundle/{Entity,Repository}' - + + + + AppBundle\Controller\: + resource: '../../src/AppBundle/Controller' + public: true diff --git a/service_container/configurators.rst b/service_container/configurators.rst index ee906b86856..855344df981 100644 --- a/service_container/configurators.rst +++ b/service_container/configurators.rst @@ -166,20 +166,22 @@ all the classes are already loaded as services. All you need to do is specify th .. code-block:: php // app/config/services.php - use AppBundle\Mail\EmailConfigurator; - use AppBundle\Mail\EmailFormatterManager; use AppBundle\Mail\GreetingCardManager; use AppBundle\Mail\NewsletterManager; + use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; - // ... - $container->autowire(EmailFormatterManager::class); - $container->autowire(EmailConfigurator::class); + // Same as before + $definition = new Definition(); + + $definition->setAutowired(true); + + $this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*'); - $container->autowire(NewsletterManager::class) + $container->getDefinition(NewsletterManager::class) ->setConfigurator(array(new Reference(EmailConfigurator::class), 'configure')); - $container->autowire(GreetingCardManager::class) + $container->getDefinition(GreetingCardManager::class) ->setConfigurator(array(new Reference(EmailConfigurator::class), 'configure')); From cff9918611c0821ce6d2ce851c05c1914f331180 Mon Sep 17 00:00:00 2001 From: HeahDude Date: Sun, 30 Jul 2017 00:24:55 +0200 Subject: [PATCH 2/2] fixup --- service_container/3.3-di-changes.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/service_container/3.3-di-changes.rst b/service_container/3.3-di-changes.rst index 597847a2504..1f21dd618d5 100644 --- a/service_container/3.3-di-changes.rst +++ b/service_container/3.3-di-changes.rst @@ -372,11 +372,10 @@ The third big change is that, in a new Symfony 3.3 project, your controllers are .. code-block:: php // app/config/services.php - use Symfony\Component\DependencyInjection\Definition; - // To use as default template - $definition = new Definition(); + // ... + // override default template $definition->setPublic(true); $this->registerClasses($definition, 'AppBundle\\Controller\\', '../../src/AppBundle/Controller/*');