How can we identify whether the class is injectable or not in Magento 2 as per the comment.
In this answer get is used by object manager, can any one tell me how to convert below class into constructor as a dependency class.
How can we treat
get
andcreate
into constructor as a dependency classes.$stockItemFactory = $this->objectManager->get('Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory'); $stockItem = $stockItemFactory->create();
1 Answer
Usually everything is injectable except models that have a table (or more) associated to it. For example the product model, the order model...
These should not be injected in the constructor because you will end up with the same class instance everywhere you inject it. And this could lead to problems.
When dealing with such classes you should inject the factory into the constructor and instantiate your class using the $factory->create()
method.
You don't need to write the factories yourself. They will be autogenerated.
You should never use the object manager to instantiate the classes. Even if it works, it's not a good practice and it will make it harder for you to write tests.
get
from the object manager acts as Mage::getSingleton
from magento 1 and create
acts as Mage::getModel
.
And you can convert your code to use DI like this.
protected $stockItemFactory;
public function __construct(
....
\Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory $stockItemFactory,
....
) {
...
$this->stockItemFactory = $stockItemFactory;
....
}
Having this set in your constructor, you can use this in your class methods (even in the constructor but below the line I mentioned) in order to instantiate your class:
$stockItem = $this->stockItemFactory->create();
I hope I covered all your questions.
-
1Thanks for the answer +1 @Marius, yes you have covered with brief answer, but a small ambiguity is Mage::getModel('') can be converted to $this->stockItemFactory->create(); but how Mage::getSingleton can be converted/used into a dependency class in Magento 2 as same (objectManager->get)? Commented Oct 20, 2016 at 6:14
-
2everything you inject in a constructor will be a singleton. so adding an instance of
\Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory
to your constructor will be equivalent toobjectManager->get('\Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory')
. You will always have the same instance of the class even if you provide it in 2 constructors of 2 different classes.– Marius ♦Commented Oct 20, 2016 at 6:16