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:
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 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 instanceget($type)
: This retrieves a cached object instanceconfigure(array $configuration)
: This configures the di
instanceThe 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.
18.118.45.162