Know everything about Dependency Injection in Magento 2

Magento 2 is no longer a buzzing term. Since Its inception one and a half years ago, developers are in love with its rich technology stack. The following post emphasizes on Dependency Injection (DI), one of the best design patterns that Magento 2 uses.
What is Dependency Injection?
In simple words Dependency means something is dependent on something. For example, there are times when you are dependent on your parents or spouses for a situation or to a certain age similarly in programming. Imagine a situation where you end up creating a class, the class which is highly dependent on the objects. Dependency is what is needed by the class to perform some functions.
Injection on the other hand means to inject something or to provide something needful and all this is done by a third person. Technically speaking, injection is said when it passes off that particular dependency to the dependent object/class. So when we combine the two, the real meaning of Dependency Injection DI is to inject the dependency into the class from another source.
Are you still in a difficult circumstance when to migrate from Magento 1 website to Magento 2? Consult the experts in providing Magento Services.
Dependency Injection Design pattern - Let’s Delve into the Details
Over the course of years, dependency injection has been one of the most significant transformations that occurred till date in Magento 2 development realm. Of course, the codebase of Magento seems to have changed to a great extent and many new things have introduced but nothing beats Dependency Injection concept.
For those who are still confused with the concept, let me provide you a classic example offered by John Munsch. When you go and get things out of a refrigerator for yourself, causing problems might be something that’s inevitable for you. For instance, you may end up leaving the door open or get something which you shouldn’t be having or any other serious issues like not even checking the expiry dates, etc. Thus, you need someone to provide desirable results.
Here in the above-stated example, the child is a collaborating class who needs to rely on his parents, i.e. the foundation class. Dependency injection is more like a win-win situation for everyone as it passes the object to the dependent class, rather than allowing the dependent class to build or find the object right from scratch.
Dependency Injection in Magento 2
First and foremost, we will list out certain types of DI in Magento 2 space.
Construction Injection - This type is quite basic in nature, all you have to do is add a parameter in class constructor to inject the dependency. For example, injecting the dependency of customerSession is quite easy when you are willing to get current customer’s data especially in the created class. I mean gone are the days when you were required to write the whole code to get customer data.
Let’s say, for example, take a look at the data block class of custom modules used to get customer’s data and also it uses viewHelper dependency to get customer names.
Code Sample: Data.php (Constructor Injection)
<?php
namespace Sparsh\Custom\Block\Data;
class Data extends \Magento\Framework\View\Element\Template
{
protected $_customerSession;
protected $_viewHelper;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Customer\Model\Session $customerSession,
\Magento\Customer\Helper\View $viewHelper
)
{
/* dependency injection of customerSession and viewHelper for Data class */
$this->_customerSession = $customerSession;
$this->_viewHelper = $viewHelper;
parent::__construct($context);
}
public function getCustomer()
{
return $this->_customerSession->getData(); /* retrive customer data */
}
public function getName()
{
/* get customer name with the help of viewHelper object's dependency injection using customer data*/
return $this->_viewHelper->getCustomerName($this->getCustomer());
}
}
?>
Now in the aforementioned example, you have a defined class for custom modules that will successfully fetch data of customerSession. Moreover, here data class has used object customerSession. This is used when we need to call the logic of get (data) method, a method where to get relevant customer section data Magento 2 developers no longer have to write a separate code.
Method Injection
Another way out is the method injection. This is said when a particular method is dependent on a class that needs to be passed anyhow. Now have you understood the concept of Magento Event’s Observer?
Take a look at the code very carefully. Its best example of sales-order-place-after events Order Number Observer.
Code Sample: OrderNumber.php(Method Injection)
<?php
namespace Sparsh\Custom\Observer;
use Magento\Framework\Event\ObserverInterface;
class OrderNumber implements ObserverInterface {
/**
* @param Magento\Framework\Event\Observer $observer
*/
public function execute(\Magento\Framework\Event\Observer $observer) {
$order = $observer->getEvent()->getOrder();
/* Do Something Here */
}
}
?>
To explain things in an easy manner. Here the Magento/Framework/Event/Observer will be served as Dependency injection for OrderNumber class’s execute () method or we can say that execute () method function of Order Number class will be highly dependent on Magento/Framework/Event/Observer to get order object scored.
Why does one need to use it?
DI can be considered as an idiom for Magento 2. However, while creating objects using DI is more work than creating them on a direct basis. So, I would suggest succeeding in the present era, one requires to get themselves into the habit of using DI always.
Although, you can think of creating objects via PHP’s new operator but that doesn’t make DI less of a concept. Try keeping these practices at a minimum and you will soon find that using dependency injection is way more beautiful than explicit instantiation.
What was the problem back then?
By now I am pretty sure you must have understood the concept of DI, i.e. to remove the direct dependency of the objects with class. And to accomplish, the given task we need to use the third class to create objects for that class. I am talking about the object manager in Magento 2.
So, what’s the issue then? Why should we remove this direct dependency? Now imagine you are using a third-party library to calculate tax. As soon as a new update comes, say for example a new library is released which has the taxation class has parameterized. So, the question is how you are going to update your code?
Simple, consider Dependency Injection in Magento 2
<?php
class Product {
protected $_taxation;
public function __construct(
\Taxation $taxation
) {
$this->_taxation = $taxation;
}
public function getTax($id) {
return $this->_taxation->getCalculateTax($id);
}
}
In the above code, you won’t find any use of a new keyword for creating the object of taxation class. But in the case of a non-parameterized taxation class, managing parameterized class can be quite difficult. Here's when the dependency Injection design pattern comes into play.
So what needs to be done is create a di.xml file in your Magento 2 module and make this code entry:
<type name="/Taxation">
<arguments>
<argument name="%newParam%" xsi:type="%anyType%">%Argument%</argument>
</arguments>
</type>
This means when the object manager will create the object of the taxation class it will first and foremost check its type declaration and will add the %newparam% value for its object’s constructor. It may also interest you to know that you can also define any type of argument here in xsi:type like an object, string, int, etc.
Enters the reflection. In simple words reflection means to introspect, examine about self. But when we are talking about programming reflection, it means a PHP library that provides an essential way to check any class member variables, functions, constructor parameters and so more. If simply put, reflection in Magento signifies the class which is going to instantiate.