¿Es posible inyectar una dependencia en un modelo Magento 2 CRUD?
Eso es - Magento 2 tiene una clase base abstracta modelo: Magento\Framework\Model\AbstractModel
. Si desea crear un objeto modelo simple Crear, Leer, Actualizar, Eliminar, amplíe esta clase con su propia clase.
class Foo extends Magento\Framework\Model\AbstractModel
{
}
¿Es posible tener dependencias inyectadas en el __construct
método de su modelo ? Cuando lo intento, termino obteniendo el siguiente error.
Error fatal: no se puede crear una instancia de la clase abstracta Magento \ Framework \ Model \ ResourceModel \ AbstractResource
El culpable parece ser el AbstractModel
's __construct
método.
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 = []
) {
Hay dos sugerencias de tipo en este constructor ( Magento\Framework\Model\ResourceModel\AbstractResource
, Magento\Framework\Data\Collection\AbstractDb
) que no son interfaces de administrador de objetos de Magento. Son clases abstractas. Cuando extiendo esta clase e intento agregar mi dependencia inyectada
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 rescata cuando el administrador de objetos intenta instanciar las clases abstractas.
Puedo "arreglar" esto moviendo mi dependencia de objeto frente a las clases abstractas
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 = [],
) {
Sin embargo, esto cambió el orden del argumento. En una clase que estaba completamente administrada por objetos, esto no sería un problema. Sin embargo, el hecho de que existan estas sugerencias de tipo de clase abstracta implica que hay partes del sistema Magento que crearán manualmente (es decir, no a través del administrador de objetos o DI) objetos CRUD y pasarán objetos que se ajusten a las sugerencias de tipo en ese orden específico .
¿Es esto seguro? es decir, ¿estas clases abstractas en el constructor de un modelo abstracto son solo código heredado y no se usan? ¿O algunas partes del sistema seguirán usándolas, lo que significa que no es posible inyectar dependencias en un modelo CRUD?
fuente
Esto parece ser seguro. Al menos, Magento está haciendo esto en varios lugares. Vea los métodos __construct en la siguiente lista (no exclusiva) de clases para ver ejemplos
Lamentablemente, no puedo responder la otra parte de tu pregunta.
fuente
$mine
es un parámetro obligatorio , while$resource
,$resourceCollection
y$data
son opcionales . Los parámetros opcionales siempre deben ir al final, de lo contrario es imposible trabajar con ellos como con los opcionales. Por lo tanto, me parece bien que debe especificar$mine
antes que cualquier parámetro opcional.fuente
$mine
al frente de la cola creará errores. Si el código del sistema central de Magento no los usa, ¿por qué están allí? Esa es la pregunta a la que intento llegar. El hecho de que pueda usar mi modelo con el parámetro movido no lo hace seguro.$mine
antes de los parámetros opcionales, se vuelven realmente opcionales y Magento simplemente pasa los valores predeterminados (null
,array()
). Si coloca un parámetro requerido después de los opcionales, PHP considera los parámetros opcionales como obligatorios y Magento intentó instanciarlos (pero no hay preferencias para ellos).