Is it possible to inject a dependency into a Magento 2 CRUD model?
That is -- Magento 2 has a base abstract model class: Magento\Framework\Model\AbstractModel
. If you want to create a simple Create, Read, Update, Delete model object, you extend this class with your own class.
class Foo extends Magento\Framework\Model\AbstractModel
{
}
Is it possible to have injected dependencies in your model's __construct
method? When I try, I end up getting the following error.
Fatal error: Cannot instantiate abstract class Magento\Framework\Model\ResourceModel\AbstractResource
The culprit seems to be the AbstractModel
's __construct
method.
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
) {
There are two type hints in this constructor (Magento\Framework\Model\ResourceModel\AbstractResource
, Magento\Framework\Data\Collection\AbstractDb
) that are not Magento object manager interfaces. They're abstract classes. When I extend this class and try to add my injected dependency
class Foo extends Magento\Framework\Model\AbstractModel
{
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = [],
\Package\Module\Model\Mine $mine,
) {
//...
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
}
}
Magento bails when the object manager tries to instantiate the abstract classes.
I can "fix" this by moving my object dependency in front of the abstract classes
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Package\Module\Model\Mine $mine,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = [],
) {
However, this changed the argument order. In a class that was fully object managed, this wouldn't be a problem. However, the fact that these abstract class type hints exists imply there are parts of the Magento system that will manually (i.e. not via the object manager or DI) instantiate CRUD objects and pass in objects that conform to the type hints in that specific order.
Is this safe? i.e. Are these abstract classes in an abstract model's constructor just legacy code, and not used? Or will parts of the system still use these, meaning it's not possible to inject dependencies into a CRUD model?