Chapter 5. Using the Dependency Injection

Dependency injection is a software design pattern via which one or more dependencies are injected or passed by reference into an object. What this exactly means on a practical level is shown in the following two simple examples:

public function getTotalCustomers()
{
    $database = new PDO( … );
    $statement = $database->query('SELECT …');
    return $statement->fetchColumn();
}

Here, you will see a simplified PHP example, where the $database object is created in the getTotalCustomers method. This means that the dependency on the database object is being locked in an object instance method. This makes for tight coupling, which has several disadvantages such as reduced reusability and a possible system-wide effect caused by changes made to some parts of the code.

A solution to this problem is to avoid methods with these sorts of dependencies by injecting a dependency into a method, as follows:

public function getTotalCustomers($database)
{
    $statement = $database->query('SELECT ...');
    return $statement->fetchColumn();
}

Here, a $database object is passed (injected) into a method. That's all that dependency injection is—a simple concept that makes code loosely coupled. While the concept is simple, it may not be easy to implement it across large platforms such as Magento.

Magento has its own object manager and dependency injection mechanism that we will soon look at in detail in the following sections:

  • The object manager
  • Dependency injection
  • Configuring class preferences
  • Using virtual types

Note

To follow and test the code examples given in the following sections, we can use the code available at https://github.com/ajzele/B05032-Foggyline_Di. To install it, we simply need to download it and put it in the app/code/Foggyline/Di directory. Then, run the following set of commands on the console within Magento's root directory:

php bin/magento module:enable Foggyline_Di
php bin/magento setup:upgrade
php bin/magento foggy:di

The last command can be used repeatedly when testing the snippets presented in the following section. When php bin/magento foggy:di is run, it will run the code within the execute method in the DiTestCommand class. Therefore, we can use the __construct and execute methods from within the DiTestCommand class and the di.xml file itself as a playground for DI.

The object manager

The initializing of objects in Magento is done via what is called the object manager. The object manager itself is an instance of the MagentoFrameworkObjectManagerObjectManager class that implements the MagentoFrameworkObjectManagerInterface class. The ObjectManager class defines the following three methods:

  • create($type, array $arguments = []): This creates a new object instance
  • get($type): This retrieves a cached object instance
  • configure(array $configuration): This configures the di instance

The object manager can instantiate a PHP class, which can be a model, helper, or block object. Unless the class that we are working with has already received an instance of the object manager, we can receive it by passing ObjectManagerInterface into the class constructor, as follows:

public function __construct(
    MagentoFrameworkObjectManagerInterface $objectManager
)
{
    $this->_objectManager = $objectManager;
}

Usually, we don't have to take care of the constructor parameter's order in Magento. The following example will also enable us to fetch an instance of the object manager:

public function __construct(
    $var1,
    MagentoFrameworkObjectManagerInterface $objectManager,
    $var2 = []
)
{
    $this->_objectManager = $objectManager;
}

Though we can still use plain old PHP to instantiate an object such as $object = new FoggylineDiModelObject(), by using the object manager, we can take advantage of Magento's advanced object features such as automatic constructor dependency injection and object proxying.

Here are a few examples of using object manager's create method to create new objects:

$this->_objectManager->create('MagentoSalesModelOrder')
$this->_objectManager->create('MagentoCatalogModelProductImage')
$this->_objectManager->create('MagentoFrameworkUrlInterface')
$this->_objectManager->create('SoapServer', ['wsdl' => $url, 'options' => $options])

The following are a few examples of using object manager's get method to create new objects:

$this->_objectManager->get('MagentoCheckoutModelSession')
$this->_objectManager->get('PsrLogLoggerInterface')->critical($e)
$this->_objectManager->get('MagentoFrameworkEscaper')
$this->_objectManager->get('MagentoSitemapHelperData')

The object manager's create method always returns a new object instance, while the get method returns a singleton.

Note how some of the string parameters passed to create and get are actually interface names and not strictly class names. We will soon see why this works with both class names and interface names. For now, it suffices to say that it works because of Magento's dependency injection implementation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.45.162