In Magento 2, they introduced the usage of dependency injection, which is a well-known design pattern that changes the way you use resources in the code. Using dependency injection, all the required resources are created when the class is instantiated instead of creating an object (through the Magento 1.x Mage
class) when necessary. The benefit of this is that it is easier to use unit testing as it is possible to mock the required objects.
In this example, we will see how to create a new record in the demolist
model created in the previous chapter. The record is created using an observer on the sales_order_place_after
event that is dispatched after a new order is saved.
Follow these steps on how to use dependency injection:
Observer
to listen to the event that we want:etc/events.xml:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="sales_order_place_after"> <observer name="sample" instance="GenmatoSampleObserverPlaceOrder"/> </event> </config>
Observer
class as defined in step 1:Observer/PlaceOrder.php:
<?php namespace GenmatoSampleObserver; use MagentoFrameworkEventObserverInterface; use MagentoFrameworkEventObserver as EventObserver; use GenmatoSampleModelDemoFactory; class PlaceOrder implements ObserverInterface { /** * @var DemoFactory */ protected $demoFactory; /** * @param DemoFactory $demoFactory */ public function __construct(DemoFactory $demoFactory) { $this->demoFactory = $demoFactory; } /** * Add record to demoList when new order is placed * * @param EventObserver $observer * @return void */ public function execute(EventObserver $observer) { /** @var MagentoSalesModelOrder $order */ $order = $observer->getEvent()->getOrder(); $demoList = $this->demoFactory->create(); $demoList->setTitle(__('New order (%1) placed!', $order->getIncrementId())); try { $demoList->save(); } catch (Exception $ex) { // Process error here.... } } }
bin/magento cache:clean
In the Observer
class defined in step 2, the object that we need to create a new record in is injected into the constructor function:
public function __construct(DemoFactory $demoFactory)
During the instantiation of the class, the necessary classes are injected by the Magento 2 dependency injection (DI) framework. In this case, it adds the GenmatoSampleModelDemoFactory
class to the constructor. This class is not a real existing class; this is because the class that we want to use is a non-injectable class. A non-injectable class is a class that you create yourself through the new [classname]
command or the Mage::getModel()
call in Magento 1.x. With the use of dependency injection, creating a new object should be handled by the object manager, but in order to be able to use unit testing, it is not advisable to create the object directly in the code. To solve this, the Magento framework uses autogenerated classes. In this example, the generated class is stored in var/generation/Genmato/Sample/Model/DemoFactory.php
:
<?php namespace GenmatoSampleModel; /** * Factory class for @see GenmatoSampleModelDemo */ class DemoFactory { /** * Object Manager instance * * @var MagentoFrameworkObjectManagerInterface */ protected $_objectManager = null; /** * Instance name to create * * @var string */ protected $_instanceName = null; /** * Factory constructor * * @param MagentoFrameworkObjectManagerInterface $objectManager * @param string $instanceName */ public function __construct(MagentoFrameworkObjectManagerInterface $objectManager, $instanceName = '\Genmato\Sample\Model\Demo') { $this->_objectManager = $objectManager; $this->_instanceName = $instanceName; } /** * Create class instance with specified parameters * * @param array $data * @return GenmatoSampleModelDemo */ public function create(array $data = array()) { return $this->_objectManager->create($this->_instanceName, $data); } }
In this case, the autogenerated class is a Factory
class that has only the create()
function available. In the create function, the object manager is used to instantiate the GenmatoSampleModelDemo
class; this object can then be used to load an existing record or create a new record and save the data stored in the object.
3.144.9.124