Quando eu acho que envolvi o sistema DI do Magento 2, algo aparece e o quebra.
Vejo no código principal maneiras diferentes de acessar um auxiliar.
Por exemplo, Magento\Catalog\Controller\Category::_initCategory
existe isso:
if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
return false;
}
Mas no Magento\Catalog\Block\Category\View
ajudante é injetado no construtor
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Model\Layer\Category $catalogLayer,
\Magento\Framework\Registry $registry,
\Magento\Catalog\Helper\Category $categoryHelper,
array $data = array()
) {
$this->_categoryHelper = $categoryHelper;
$this->_catalogLayer = $catalogLayer;
$this->_coreRegistry = $registry;
parent::__construct($context, $data);
}
Isso me levou a pensar que os auxiliares deveriam ser acessados de maneira diferente em controladores e blocos (e modelos), mas então encontrei um controlador em que um auxiliar é injetado no construtor Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute
.
Por favor, limpe o nevoeiro para mim.
Quando devo usar DI e quando devo usar objectManager
? e porque?
Eu li esta pergunta: Instanciando auxiliares no Magento 2 . Esta é apenas uma pergunta de acompanhamento sobre isso.
fonte
Não sei muito sobre a implementação do Magento, mas parece que
ObjectManager
é um localizador de serviço .Geralmente, o uso de um Localizador de Serviço para acessar dependências em um objeto é bastante ruim, confira este artigo .
Definir explicitamente suas dependências através de um construtor é uma abordagem muito melhor. Ajuda nos testes de unidade e nos problemas de tempo de execução, com os serviços não sendo definidos.
Injetar o Gerenciador de Objetos em uma classe é basicamente injetar um Registro em sua classe que tenha acesso a todos os serviços de seus aplicativos, o que obviamente não está certo.
Eu uso o ZF2 um pouco e geralmente defino pequenas classes de fábrica para Serviços, Controladores e qualquer classe que exija dependências. Essas classes de fábrica têm acesso ao Localizador de serviços e agarram todos os serviços dos quais o objeto depende e os injetam através do construtor. Usar um Localizador de Serviço em uma classe Factory é bom, pois é na maioria das vezes descartável, algo como isso, por exemplo.
Essas fábricas ainda são fáceis de testar .
IMO, use injeção de construtor sempre que possível. Novamente, eu não sei muito sobre a implementação do Magento e se ele tem o conceito de Fábricas, a partir de uma rápida olhada, parece que ele as suporta, mas definir explicitamente suas classes e usar um Localizador de Serviço para construí-las nas classes Factory é uma abordagem muito mais limpa.
Isto é de alguém que tem exposição limitada aos padrões mencionados acima, então eu também gostaria de ouvir os pensamentos / experiências de outras pessoas sobre o assunto!
Mais leitura
fonte
Uma outra maneira de usar o auxiliar (nos modelos) é:
Espero que seja útil se você ainda não sabia.
fonte
Embora seja uma pergunta antiga, não tenho certeza se Marius recebeu sua resposta. Acredito que Marius possa responder melhor. Eu gostaria de responder em resumo. Por que o Magento 2 sugere usar DI em vez de auxiliar?
Por que o núcleo M2 pode não usar DI em alguns casos?
Embora o módulo de catálogo Core tenha sido usado como auxiliar, ele utilizou DI extensivamente. Em minha pesquisa, descobri que o Magento 2 utilizava poucas funções nos arquivos auxiliares do Catálogo Principal que não são adequadas para Contratos de Serviço.
Se você precisar usar explicitamente uma classe definida pelo Magento (como \ Magento \ Catalog \ Model \ Product), torne a dependência implícita explícita, dependendo da implementação concreta em vez da interface do contrato de serviço.
Sem dúvida, o desenvolvedor de extensões deve usar DI em vez de Magento1 como Helper. Ao implementar de acordo com as diretrizes do Magento 2, as consequências são limitadas. Ao quebrar as recomendações, problemas acontecem.
fonte