Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • SensioLabs Professional services to help you with Symfony
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. Documentation
  3. Components
  4. Dependency Injection
  5. The Dependency Injection Component
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • Installation
  • Basic Usage
  • Avoiding Your Code Becoming Dependent on the Container
  • Setting Up the Container with Configuration Files

The Dependency Injection Component

Edit this page

Warning: You are browsing the documentation for Symfony 2.0, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

The Dependency Injection Component

The Dependency Injection component allows you to standardize and centralize the way objects are constructed in your application.

For an introduction to Dependency Injection and service containers see Service Container

Installation

You can install the component in many different ways:

  • Use the official Git repository (https://github.com/symfony/DependencyInjection);
  • Install it via Composer (symfony/dependency-injection on Packagist).

Basic Usage

You might have a simple class like the following Mailer that you want to make available as a service:

1
2
3
4
5
6
7
8
9
10
11
class Mailer
{
    private $transport;

    public function __construct()
    {
        $this->transport = 'sendmail';
    }

    // ...
}

You can register this in the container as a service:

1
2
3
4
use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container->register('mailer', 'Mailer');

An improvement to the class to make it more flexible would be to allow the container to set the transport used. If you change the class so this is passed into the constructor:

1
2
3
4
5
6
7
8
9
10
11
class Mailer
{
    private $transport;

    public function __construct($transport)
    {
        $this->transport = $transport;
    }

    // ...
}

Then you can set the choice of transport in the container:

1
2
3
4
5
6
use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
    ->register('mailer', 'Mailer')
    ->addArgument('sendmail');

This class is now much more flexible as you have separated the choice of transport out of the implementation and into the container.

Which mail transport you have chosen may be something other services need to know about. You can avoid having to change it in multiple places by making it a parameter in the container and then referring to this parameter for the Mailer service's constructor argument:

1
2
3
4
5
6
7
use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container->setParameter('mailer.transport', 'sendmail');
$container
    ->register('mailer', 'Mailer')
    ->addArgument('%mailer.transport%');

Now that the mailer service is in the container you can inject it as a dependency of other classes. If you have a NewsletterManager class like this:

1
2
3
4
5
6
7
8
9
10
11
class NewsletterManager
{
    private $mailer;

    public function __construct(\Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    // ...
}

Then you can register this as a service as well and pass the mailer service into it:

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();

$container->setParameter('mailer.transport', 'sendmail');
$container
    ->register('mailer', 'Mailer')
    ->addArgument('%mailer.transport%');

$container
    ->register('newsletter_manager', 'NewsletterManager')
    ->addArgument(new Reference('mailer'));

If the NewsletterManager did not require the Mailer and injecting it was only optional then you could use setter injection instead:

1
2
3
4
5
6
7
8
9
10
11
class NewsletterManager
{
    private $mailer;

    public function setMailer(\Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    // ...
}

You can now choose not to inject a Mailer into the NewsletterManager. If you do want to though then the container can call the setter method:

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();

$container->setParameter('mailer.transport', 'sendmail');
$container
    ->register('mailer', 'Mailer')
    ->addArgument('%mailer.transport%');

$container
    ->register('newsletter_manager', 'NewsletterManager')
    ->addMethodCall('setMailer', array(new Reference('mailer')));

You could then get your newsletter_manager service from the container like this:

1
2
3
4
5
6
7
use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();

// ...

$newsletterManager = $container->get('newsletter_manager');

Avoiding Your Code Becoming Dependent on the Container

Whilst you can retrieve services from the container directly it is best to minimize this. For example, in the NewsletterManager you injected the mailer service in rather than asking for it from the container. You could have injected the container in and retrieved the mailer service from it but it would then be tied to this particular container making it difficult to reuse the class elsewhere.

You will need to get a service from the container at some point but this should be as few times as possible at the entry point to your application.

Setting Up the Container with Configuration Files

As well as setting up the services using PHP as above you can also use configuration files. This allows you to use XML or Yaml to write the definitions for the services rather than using PHP to define the services as in the above examples. In anything but the smallest applications it make sense to organize the service definitions by moving them into one or more configuration files. To do this you also need to install the Config Component.

Loading an XML config file:

1
2
3
4
5
6
7
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;

$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(__DIR__));
$loader->load('services.xml');

Loading a YAML config file:

1
2
3
4
5
6
7
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__));
$loader->load('services.yml');

Note

If you want to load YAML config files then you will also need to install The YAML component.

If you do want to use PHP to create the services then you can move this into a separate config file and load it in a similar way:

1
2
3
4
5
6
7
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

$container = new ContainerBuilder();
$loader = new PhpFileLoader($container, new FileLocator(__DIR__));
$loader->load('services.php');

You can now set up the newsletter_manager and mailer services using config files:

1
2
3
4
5
6
7
8
9
10
11
12
parameters:
    # ...
    mailer.transport: sendmail

services:
    mailer:
        class:     Mailer
        arguments: ["%mailer.transport%"]
    newsletter_manager:
        class:     NewsletterManager
        calls:
            - [setMailer, ["@mailer"]]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<parameters>
    <!-- ... -->
    <parameter key="mailer.transport">sendmail</parameter>
</parameters>

<services>
    <service id="mailer" class="Mailer">
        <argument>%mailer.transport%</argument>
    </service>

    <service id="newsletter_manager" class="NewsletterManager">
        <call method="setMailer">
             <argument type="service" id="mailer" />
        </call>
    </service>
</services>
1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\DependencyInjection\Reference;

// ...
$container->setParameter('mailer.transport', 'sendmail');
$container
    ->register('mailer', 'Mailer')
    ->addArgument('%mailer.transport%');

$container
    ->register('newsletter_manager', 'NewsletterManager')
    ->addMethodCall('setMailer', array(new Reference('mailer')));
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:
    The life jacket for your team and your project

    The life jacket for your team and your project

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of Michael Zangerle, a Symfony contributor

    Thanks Michael Zangerle for being a Symfony contributor

    2 commits • 38 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony