Dependency injection overview
Magento 2 uses dependency injection as an alternative to the Magento 1.x
Dependency injection is the concept of the external environment injecting dependencies for an object instead of that object manually creating them internally.
In simple terms, when object A requires object or value B to fulfill a function, then B is a dependency of A.
Dependency inversion principle
When using dependency injection, we encourage you to follow the dependency inversion principle, a coding principle that stipulates you use abstractions to reduce code dependencies. This means that high level classes should use the interface of a low level class instead of working with it directly.
di.xml file maps an interface dependency to a preferred implementation class.
The object manager is a Magento service class that helps instantiate objects at the beginning of the bootstrapping process.
During class construction, the object manager injects the appropriate dependency as defined in the
Constructor signature dependencies
Magento uses class constructor signatures, not DocBlock annotations, to retrieve information about what dependencies to pass to an object’s constructor. If your code follows the dependency inversion principle and uses interfaces instead of specific implementations, you do not have to worry about class definitions.
A code compiler tool collects all the dependency information in a class and stores that information in files.
During class creation, the
ObjectManager uses this information to create concrete objects in the application.
Injection types used in Magento
This section explains the two dependency injection types used in Magento using the following example:
Magento uses constructor injection to provide dependencies through an object’s class constructor.
In the preceding example,
$menu are the dependencies provided to the class through its constructor.
You must use constructor dependency injection for all optional and required dependencies of an object.
Optional dependencies are the objects that your class uses for specific methods and scenarios. If your class does not always use these classes and instantiating them is expensive, consider using a proxy.
Method injection is when an object specifies a dependency in one of its methods instead of its constructor.
In the example, above
$command is the dependency passed into the class through the
When an object needs to act on a dependency, you can use method injection.
Injectable and newable objects
Injectable: Service objects that are singletons obtained through dependency injection.
The object manager uses the configuration in the
di.xml file to create these objects and inject them into constructors.
Newable/non-injectable: Objects obtained by creating a new class instance every time. Transient objects, such as those that require external input from the user or database, fall into this category. Attempts to inject these objects produce either an error that the object could not be created or an incorrect object that is incomplete.
For example, you cannot use a model object such as
app/code/Magento/Catalog/Model/Product.php for dependency injection.
You need to provide a product id or explicitly request a new, empty instance of that object, and since you cannot specify this in the constructor signature, Magento cannot inject the object.
Rules for using dependency injection
- Injectable objects may request other dependencies in their constructors if those objects are also injectable, but make sure you are not introducing circular dependencies.
- If an injectable object needs to produce newable objects, it must ask for a factory in its constructor since factories are injectable.
- If an injectable object needs to perform some actions on newable object, it must receive that object as a function method argument.
- You can create newable objects in services with object factories or you can pass them in as method parameters.
- Newable objects should not hold a field reference to an injectable object nor should they request one in their constructor.
- Classes must not ask for the ObjectManager itself to be passed as a constructor dependency. The only exception to this rule are custom factories with more elaborate needs than the autogenerated factories can provide.
- The ObjectManager may be used in integration tests to arrange the test environment.