Dependency Injection

If you never heard about dependency injection in Magento 2 you should first take a look at the Magento 2 documentation about dependency injection. If you checked out the the documentation or already are familiar with dependency injection in Magento 2, you will know that there are two ways to inject objects to your constructors. Take the following code as example:

// Vendor\Namespace\Model\SomeClass
// ...
public function __construct(ExampleClass $object) {
    $this->object = $object;
}
// ...

If you want to inject “$object”, one approach is to use argument replacement, another one is to use class preference. I will shortly describe these two methods and than point out the big difference between them.

Argument replacement

You can use argument replacement to configure the object manager to use another class that inherits from ExampleClass in “di.xml”:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<!-- ... -->
    <type name="Vendor\Namespace\Model\SomeClass">
        <arguments>
            <argument name="object" xsi:type="object">Vendor\Namespace\Model\AnotherExample</argument>
        </arguments>
    </type>
</config>

Class preference

You can also configure a preference to replace the class:

<!-- .... -->
<preference
    for="Vendor\Namespace\Model\Example"
    type="Vendor\Namespace\Model\AnotherExample" />
<!-- ... -->

As with argument replacement, also with class preference you can only inject classes that inherit from the same base class, in our case “ExampleClass”. So what is the big difference?

Difference between Object Argument replacement and Class Preference

The argument replacement will only replace the ‘ExampleClass $object’ in the constructor of the type defined in ‘di.xml’, in this case ‘Vendor\Namespace\Model\Someclass’. So if the object manager creates an instance of ‘Vendor\Namespace\Model\Someclass’, it will inject an object of type ‘AnotherClass’ into the ‘$object’ variable. If the object manager creates an object of any other class that has a dependency to ‘ExampleClass’ in his constructor, it will not inject an object of type ‘AnotherClass’.

A configured class preference will inject an object of the defined type in every constructor of any class. So if you want to replace your class type in the whole application, you are good to use class preference. This is very similar to the class rewrite concept in Magento 1.x. If you don’t want the dependency injection to be global, you should use the argument replacement. This can be very useful if you want to configure a dependency injection only for your custom module.