From f12564096ab57b2645336e794d6400409d2ae1a8 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 28 Nov 2015 17:34:38 +0100 Subject: [PATCH] Removed scopes article --- book/service_container.rst | 1 - cookbook/map.rst.inc | 1 - cookbook/service_container/index.rst | 1 - cookbook/service_container/scopes.rst | 244 -------------------------- 4 files changed, 247 deletions(-) delete mode 100644 cookbook/service_container/scopes.rst diff --git a/book/service_container.rst b/book/service_container.rst index 2cb08ae4078..43a69b82323 100644 --- a/book/service_container.rst +++ b/book/service_container.rst @@ -1182,7 +1182,6 @@ Learn more * :doc:`/components/dependency_injection/parentservices` * :doc:`/components/dependency_injection/tags` * :doc:`/cookbook/controller/service` -* :doc:`/cookbook/service_container/scopes` * :doc:`/cookbook/service_container/compiler_passes` * :doc:`/components/dependency_injection/advanced` diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 6f48c8247ae..6b7ab904f25 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -191,7 +191,6 @@ * :doc:`/cookbook/service_container/index` - * :doc:`/cookbook/service_container/scopes` * :doc:`/cookbook/service_container/compiler_passes` * (Event Dispatcher) :doc:`/cookbook/event_dispatcher/event_listener` diff --git a/cookbook/service_container/index.rst b/cookbook/service_container/index.rst index f66a455b788..ad6edb0882f 100644 --- a/cookbook/service_container/index.rst +++ b/cookbook/service_container/index.rst @@ -4,5 +4,4 @@ Service Container .. toctree:: :maxdepth: 2 - scopes compiler_passes diff --git a/cookbook/service_container/scopes.rst b/cookbook/service_container/scopes.rst deleted file mode 100644 index 13d35e4cc1e..00000000000 --- a/cookbook/service_container/scopes.rst +++ /dev/null @@ -1,244 +0,0 @@ -.. index:: - single: DependencyInjection; Scopes - -How to Work with Scopes -======================= - -.. caution:: - - The "container scopes" concept explained in this article has been deprecated - in Symfony 2.8 and it will be removed in Symfony 3.0. - -This article is all about scopes, a somewhat advanced topic related to the -:doc:`/book/service_container`. If you've ever gotten an error mentioning -"scopes" when creating services, then this article is for you. - -.. note:: - - If you are trying to inject the ``request`` service, the simple solution - is to inject the ``request_stack`` service instead and access the current - Request by calling the - :method:`Symfony\\Component\\HttpFoundation\\RequestStack::getCurrentRequest` - method (see :ref:`book-container-request-stack`). The rest of this entry - talks about scopes in a theoretical and more advanced way. If you're - dealing with scopes for the ``request`` service, simply inject ``request_stack``. - -Understanding Scopes --------------------- - -The scope of a service controls how long an instance of a service is used -by the container. The DependencyInjection component provides two generic -scopes: - -``container`` (the default one): - The same instance is used each time you ask for it from this container. - -``prototype``: - A new instance is created each time you ask for the service. - -The -:class:`Symfony\\Component\\HttpKernel\\DependencyInjection\\ContainerAwareHttpKernel` -also defines a third scope: ``request``. This scope is tied to the request, -meaning a new instance is created for each subrequest and is unavailable -outside the request (for instance in the CLI). - -An Example: Client Scope -~~~~~~~~~~~~~~~~~~~~~~~~ - -Other than the ``request`` service (which has a simple solution, see the -above note), no services in the default Symfony container belong to any -scope other than ``container`` and ``prototype``. But for the purposes of -this article, imagine there is another scope ``client`` and a service ``client_configuration`` -that belongs to it. This is not a common situation, but the idea is that -you may enter and exit multiple ``client`` scopes during a request, and each -has its own ``client_configuration`` service. - -Scopes add a constraint on the dependencies of a service: a service cannot -depend on services from a narrower scope. For example, if you create a generic -``my_foo`` service, but try to inject the ``client_configuration`` service, -you will receive a -:class:`Symfony\\Component\\DependencyInjection\\Exception\\ScopeWideningInjectionException` -when compiling the container. Read the sidebar below for more details. - -.. sidebar:: Scopes and Dependencies - - Imagine you've configured a ``my_mailer`` service. You haven't configured - the scope of the service, so it defaults to ``container``. In other words, - every time you ask the container for the ``my_mailer`` service, you get - the same object back. This is usually how you want your services to work. - - Imagine, however, that you need the ``client_configuration`` service - in your ``my_mailer`` service, maybe because you're reading some details - from it, such as what the "sender" address should be. You add it as a - constructor argument. There are several reasons why this presents a problem: - - * When requesting ``my_mailer``, an instance of ``my_mailer`` (called - *MailerA* here) is created and the ``client_configuration`` service ( - called *ConfigurationA* here) is passed to it. Life is good! - - * Your application now needs to do something with another client, and - you've designed your application in such a way that you handle this - by entering a new ``client_configuration`` scope and setting a new - ``client_configuration`` service into the container. Call this - *ConfigurationB*. - - * Somewhere in your application, you once again ask for the ``my_mailer`` - service. Since your service is in the ``container`` scope, the same - instance (*MailerA*) is just re-used. But here's the problem: the - *MailerA* instance still contains the old *ConfigurationA* object, which - is now **not** the correct configuration object to have (*ConfigurationB* - is now the current ``client_configuration`` service). This is subtle, - but the mis-match could cause major problems, which is why it's not - allowed. - - So, that's the reason *why* scopes exist, and how they can cause - problems. Keep reading to find out the common solutions. - -.. note:: - - A service can of course depend on a service from a wider scope without - any issue. - -Using a Service from a Narrower Scope -------------------------------------- - -There are two solutions to the scope problem: - -* A) Put your service in the same scope as the dependency (or a narrower one). If - you depend on the ``client_configuration`` service, this means putting your - new service in the ``client`` scope (see :ref:`changing-service-scope`); - -* B) Pass the entire container to your service and retrieve your dependency from - the container each time you need it to be sure you have the right instance - -- your service can live in the default ``container`` scope (see - :ref:`passing-container`). - -Each scenario is detailed in the following sections. - -.. _using-synchronized-service: - -.. note:: - - Prior to Symfony 2.7, there was another alternative based on ``synchronized`` - services. However, these kind of services have been deprecated starting from - Symfony 2.7. - -.. _changing-service-scope: - -A) Changing the Scope of your Service -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Changing the scope of a service should be done in its definition. This example -assumes that the ``Mailer`` class has a ``__construct`` function whose first -argument is the ``ClientConfiguration`` object: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/services.yml - services: - my_mailer: - class: AppBundle\Mail\Mailer - scope: client - arguments: ["@client_configuration"] - - .. code-block:: xml - - - - - - - - - .. code-block:: php - - // app/config/services.php - use Symfony\Component\DependencyInjection\Definition; - - $definition = $container->setDefinition( - 'my_mailer', - new Definition( - 'AppBundle\Mail\Mailer', - array(new Reference('client_configuration'), - )) - )->setScope('client'); - -.. _passing-container: - -B) Passing the Container as a Dependency of your Service -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Setting the scope to a narrower one is not always possible (for instance, a -twig extension must be in the ``container`` scope as the Twig environment -needs it as a dependency). In these cases, you can pass the entire container -into your service:: - - // src/AppBundle/Mail/Mailer.php - namespace AppBundle\Mail; - - use Symfony\Component\DependencyInjection\ContainerInterface; - - class Mailer - { - protected $container; - - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - public function sendEmail() - { - $request = $this->container->get('client_configuration'); - // ... do something using the client configuration here - } - } - -.. caution:: - - Take care not to store the client configuration in a property of the object - for a future call of the service as it would cause the same issue described - in the first section (except that Symfony cannot detect that you are - wrong). - -The service configuration for this class would look something like this: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/services.yml - services: - my_mailer: - class: AppBundle\Mail\Mailer - arguments: ["@service_container"] - # scope: container can be omitted as it is the default - - .. code-block:: xml - - - - - - - - - .. code-block:: php - - // app/config/services.php - use Symfony\Component\DependencyInjection\Definition; - use Symfony\Component\DependencyInjection\Reference; - - $container->setDefinition('my_mailer', new Definition( - 'AppBundle\Mail\Mailer', - array(new Reference('service_container')) - )); - -.. note:: - - Injecting the whole container into a service is generally not a good - idea (only inject what you need). pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy