Types of dependency injections

Types of dependency injections

Using dependency injection you can make class more reusable, testable and decoupled from others. There are several types that the dependencies can be injected.

Constructor Injection:

This is very common method to inject dependencies via class’s constructor. To implement it you need to add an argument to constructor to accept dependency.

namespace App\Mail;

class SubscriptionManager
{
    private $translator;

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

If you want specify which service you want to inject into this in the service container configuration:

services:
    App\Mail\SubscriptionManager:
        arguments: ['@translator']

Immutable-setter Injection:

This is another type of injection to use a method which returns a separate instance by cloning the original service, in this way you can make a service immutable.
Immutable setters works with optional dependencies, so if you don’t want dependency then this setter don’t need to be called.
Using immutable setters force the dependency to stay the same during the lifetime of a service like constructor injection.

class SubscriptionManager
{
    private $translator;
    
    /**
     * @required
     * @return static
     */
    public function withTranslator(TranslatorInterface $translator)
    {
        $new = clone $this;
        $new-> translator = $translator;
        return $new;
    }
}
services:
     App\Mail\SubscriptionManager
         calls:
             - [withTranslator, ['@translator'], returns_clone: true]

Setter Injection:

Another possible injection point into a class is by adding a setter method that accepts the dependency.
This injection works well with optional dependencies. If you do not need the dependency, then do not call the setter.

class SubscriptionManager
{
    private $translator;

    public function setTranslator( TranslatorInterface $translator)
    {
        $this-> translator = $translator;
    }
}
services:
    App\Mail\SubscriptionManager:
        calls:
            - [setMailer, ['@translator']]

Property Injection:

In this injection, you can set public fields of the class directly.

class SubscriptionManager
{
    private $translator;
}
services:
    class: App\Mail\SubscriptionManager
        properties:
            translator: '@translator'

In this type of dependency you cannot control as its set at all, it can be change at any point in the lifetime of object.
As you can’t use type hinting so you can’t be sure that which dependency has been injected except by writing into the class code to explicitly test the instance of class before using it.