É possível injetar uma dependência em um modelo CRUD do Magento 2?
Isso é - Magento 2 tem uma base de classe modelo abstrato: Magento\Framework\Model\AbstractModel
. Se você deseja criar um objeto de modelo simples Criar, Ler, Atualizar, Excluir, estende essa classe com sua própria classe.
class Foo extends Magento\Framework\Model\AbstractModel
{
}
É possível injetar dependências no __construct
método do seu modelo ? Quando tento, acabo recebendo o seguinte erro.
Erro fatal: Não é possível instanciar a classe abstrata Magento \ Framework \ Model \ ResourceModel \ AbstractResource
O culpado parece ser o 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 = []
) {
Existem duas dicas de tipo neste construtor ( Magento\Framework\Model\ResourceModel\AbstractResource
, Magento\Framework\Data\Collection\AbstractDb
) que não são interfaces do gerenciador de objetos Magento. São aulas abstratas. Quando estendo essa classe e tento adicionar minha dependência injetada
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);
}
}
O Magento falha quando o gerenciador de objetos tenta instanciar as classes abstratas.
Eu posso "consertar" isso movendo minha dependência de objeto na frente das classes abstratas
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 = [],
) {
No entanto, isso mudou a ordem dos argumentos. Em uma classe totalmente gerenciada por objetos, isso não seria um problema. No entanto, o fato de que essas dicas de tipo de classe abstrata existem implica que há partes do sistema Magento que instanciam manualmente (ou seja, não através do gerenciador de objetos ou DI) instanciam objetos CRUD e passam objetos que estão em conformidade com as dicas de tipo nessa ordem específica .
Isso é seguro? ou seja, essas classes abstratas no construtor de um modelo abstrato são apenas código legado e não são usadas? Ou partes do sistema ainda as usarão, o que significa que não é possível injetar dependências em um modelo CRUD?
fonte
Parece seguro. Pelo menos, o magento está fazendo isso em vários lugares. Consulte os métodos __construct na seguinte lista (não exclusiva) de classes para obter exemplos
Infelizmente, não consigo responder à outra parte da sua pergunta.
fonte
$mine
é um exigido parâmetro, enquanto$resource
,$resourceCollection
e$data
são opcionais . Parâmetros opcionais sempre devem durar, caso contrário, é impossível trabalhar com eles como com o opcional. Portanto, parece-me bom que você especifique$mine
antes de qualquer parâmetro opcional.fonte
$mine
para a frente da fila criará erros. Se o código do sistema principal do Magento não os utiliza, por que eles estão lá? Essa é a pergunta que estou tentando chegar ao fundo. Só porque eu posso usar meu modelo com o parâmetro movido não o torna seguro.$mine
antes dos parâmetros opcionais, eles se tornam realmente opcionais e o Magento passa apenas os valores padrão (null
,array()
). Se você colocar um parâmetro necessário após os opcionais, o PHP considerará os parâmetros opcionais como necessários e o Magento tentará instancia-los (mas não há preferências para eles).