New in Symfony 2.8: Deprecating Scopes and Introducing Shared Services

Contributed by
Diego Saint Esteben in #14984.

Service scopes control how long an instance of a service is used by the container. The DependencyInjection component provides three scopes:

  • container (the default one) where the same instance is used each time you ask for a service from the container;
  • prototype where a new instance is created each time you ask for the service;
  • request where a new instance is created for each subrequest (and it's unavailable outside the request).

The request_stack service, introduced in Symfony 2.4, solved the problems related to the request scope and dealing with the Request object in services. This made us rethink the entire "scope" concept and we decided to simplify the DependencyInjection component deprecating them entirely in Symfony 2.8 and removing them in Symfony 3.0.

The new shared option

Instead of scope, service definitions can now configure a shared option. By default this option is true, which is equivalent to the previous container scope. Set it to false to get the same result as in the previous prototype scope:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# app/config/services.yml
# BEFORE
services:
    app.my_service:
        class: AppBundle\Service\MyService
        scope: prototype

# AFTER
services:
    app.my_service:
        class:  AppBundle\Service\MyService
        shared: false

This deprecation may seem small, but it will produce significant benefits, such as easing the learning curve of Symfony and eliminating hard to understand exceptions (e.g. ScopeWideningInjectionException).

Comments

I like that, the scope configuration was weird. Shared would exactly do what a developer expect from a service.

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.