Understanding The Key Aspects of Dependency Injection in Magento 2

[Guest post by Jason Roiz from OSSMedia]

Magento 2 has already set the game and one of the biggest changes that online players will witness in this version is the use of dependency injection. Dependency injection is a design pattern which has been introduced as a substitute of Mage class used in Magento 1 for managing dependencies.

What is Dependency Injection?

As a part of solid, dependency injection makes sure that all the dependents are decoupled points, which create a system as and when they are combined with a system. It helps Magento programmers to implements version control and provides a program with an ability to follow the principles of dependency inversion.

Here, each dependent has been assigned with their own task and they are responsible for performing that only. The other tasks that a dependent requires to function, called the dependencies, are injected into the dependent.

To illustrate how it solves the problem, we are providing you an example below using the Magento 1.X core snippet.

public function getMail() 
{ 
    if (is_null($this->_mail)) { 
        $this->_mail = new Zend_Mail('utf-8'); 
    } 
    return $this->_mail; 
}

The above method has been taken from the Mage_Core_Model_Email_Template class. You can see above that the class is hard coded dependent of Zend_mail. In case where you feel the need of replacing the file with an entirely different library you will have to perform some modifications within the code file.

A constructor parameter could have been included in Mage_Core_Model_Email_Template or any method which could inject the dependency. Although, it would have to be a sub-class of Zend_mail which comes with same interface to avoid compatibility issues. That’s the reason why dependency injection in Magento 1.x could not be implemented.

This is something which increases the complexity of code and resolving dependency problems while implementing it, called for a complete new approach.

However, with dependency injection, there is no need for an object to locate an object or value on which it depends. Instead an environment will be created for providing dependency. As a special design pattern, it helps you implement control version and facilitates a program with an ability to follow the principles of dependency injection.

The primary goal of dependency injection is to minimize dependence- and make it absolutely easier to manage. Everything is testable, but also maintainable and flexible. This way Magento 2 will now upgraded straightaway for the purpose of unit testing.

Elements of DI

There are mainly four elements of DI:

  • Implementation of service object
  • A client object
  • An interface connecting client with the service

An injector object, which injects services to the client.

Dependency Injection in Magento 2

In Magento 2, DI has been introduced as an alternative of Magento 1.x Mage class. In simple words, Magento 1 needs an access to some of the functions of Magento 2. In this way, Magento 1 is the consumer and Magento 2 is the dependent.

The process of reducing the coding dependencies is known as dependency inversion. The basic principle of dependency inversion is that both high and low modules should rely upon the services offered by Magento 2. Details will depend on abstractions, whereas abstractions will work independently.

Constructor Injection

In Magento 2, constructors are being used for creating class dependencies. All the needed dependencies are to be declared directly in the constructor signature.

The basic objective of constructor injection is to be used with both required as well as optional service dependencies of an object. For the expensive ones, proxy patterns could be used. The best part is all of them are auto-generated and do not require you to deal with complicated coding.

This is how a sample proxy could be declared in di.xml:

 
 
Magento\Backend\Model\Config\Structure\Element\Group\Proxy 
 
 

_bar = $bar; 
} 

public function execute() 
{ 
//some code 

$this->_bar->execute(); 

//some code 
} 
} 
$bar = new Bar(); 
$foo = new Foo($bar); 
$foo->execute();

Method Injection

Method injection is used for API objects that your objects are dependent upon. Below we have mentioned an example which explains the type of injection to declare $menu and $itemFactory as service dependencies, and $command is used as an API parameter for your objects.

_itemFactory = $menuItemFactory; 
$this->_menu = $menu; 
} 

public function processCommand(\Magento\Backend\Model\Menu\Builder\CommandAbstract $command) // API param 
{ 
if (!isset($this->_commands[$command->getId()])) { 
$this->_commands[$command->getId()] = $command; 
} else { 
$this->_commands[$command->getId()]->chain($command); 
} 
return $this; 
} 
}

Configuring Your Application for DI

Below are the required configurations used to run and compose the application.

  • Class Definitions – a must have component of constructor. It allows you define which type of dependency should be passed to an object.
  • Instant Configurations – defines the way an object could be instantiated and also its life cycle.
  • Abstract Implementation Mappings – define the type of implementation to be used based on the request.

Class Definitions

Magento uses class constructor signatures for specifying the information about the class dependencies. It reads constructors which make use of reflection. It is always beneficial to use the Magento definition compiler tool to pre-compile class definitions to ensure a high level of performance.

Configuration Types

This is how the dependency injection by type looks:

 
 
 
 
 
 
 
 
system 
 
 
 
 
moduleConfig 
 
 

The above example showcases these three types:

  • config – virtual type extending Magento/Core/Model/Config
  • moduleConfig – extends Magento/Core/Model/Config
  • Magento/Core/Model/App – retrieves moduleConfig as a dependency

Arguments

Arguments are generally injected into the class instance at the time of their creation. Also, the name of the parameters must also be in compatible with the class constructor parameters.

Parameter – declared in the constructor signature variable
Argument – it’s basically a value which is being used when a class is being created.

Wrapping Up

Dependency injection is an integral part of Magento 2 and is all set to provide multiple benefits for those opting for Magento development services. It is sure to be a major step towards the improvement of tightly coupled code and components separations.

Subscribe to our mailing list

Our Personalization Solution


Want to increase conversions and sales of your eCommerce Website? Discover our 360º eCommerce Personalization Solution and Try it for Free!


Post your thoughts