Pergunta

Quando penso que estou pensando no sistema DI do Magento 2, algo surge e o desembrulha.
Vejo no código principal diferentes maneiras de acessar um auxiliar.
Por exemplo em Magento\Catalog\Controller\Category::_initCategory existe isso:

if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
    return false;
}

Mas em Magento\Catalog\Block\Category\View o auxiliar é 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 helpers deveriam ser acessados ​​de forma diferente em controladores e blocos (e modelos), mas então encontrei um controlador onde um helper é injetado no construtor Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute.

Por favor, limpe a névoa para mim.
Quando devo usar DI e quando devo usar objectManager?e porque?
Eu li esta pergunta: Instanciando Helpers no Magento 2.Esta é apenas uma pergunta de acompanhamento sobre isso.

Foi útil?

Solução

Eu preferiria DI sempre que possível, pois usar o gerenciador de objetos já é uma violação da lei de Demeter.Ao usar o gerenciador de objetos, essas dependências ficam ocultas apenas na lógica do método.

Outras dicas

Não sei muito sobre a implementação do Magento, mas parece que o ObjectManager é um Localizador de serviços.

Geralmente usar um Service Locator para acessar dependências em um objeto é muito ruim, confira Este artigo.

Definir explicitamente suas dependências por meio de um construtor é uma abordagem muito melhor.Ajuda em testes de unidade e problemas de tempo de execução com serviços não definidos.

Injetar o Gerenciador de Objetos em uma classe é basicamente injetar um Registro na sua classe que tem acesso a todos os serviços do seu aplicativo, o que obviamente não está certo.

eu uso ZF2 bastante e geralmente definem 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 Service Locator e capturam todos os serviços dos quais o objeto depende e os injetam através do construtor.Usar um Service Locator em uma classe Factory é bom, pois é principalmente código descartável, algo como esse por exemplo.

Estas fábricas ainda são fáceis de teste.

IMO, use injeção de construtor sempre que possível.Novamente, não sei muito sobre a implementação do Magento e se ele tem o conceito de Fábricas, à primeira vista parece que as suporta, mas definir explicitamente suas classes e usar um Localizador de Serviço para construí-las nas classes de Fábrica é uma abordagem muito mais limpa.

Isto vem de alguém que tem exposição limitada aos padrões mencionados acima, então eu também gostaria de ouvir as opiniões/experiências de outras pessoas sobre o assunto!

Mais leitura

Uma outra maneira de usar o auxiliar (em modelos) é:

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]')->getMethodName();

Espero que seja útil caso você ainda não saiba.

Embora seja uma questão antiga, não tenho certeza se Mário obteve sua resposta.Eu acredito Mário pode responder melhor.Eu gostaria de responder resumidamente.Por que o Magento 2 sugere usar DI em vez de auxiliar?

  • Tornando possível/fácil o isolamento em testes unitários
  • Definindo explicitamente as dependências de uma classe
  • Facilitar uma boa concepção (princípio da responsabilidade única (SRP) para exemplo)
  • Usar DI em seu módulo reduz o risco de bugs de incompatibilidade quando O Magento muda a implementação subjacente dessas interfaces.Este é um conceito importante a ser entendido pelos desenvolvedores de extensões.

Por que o núcleo M2 pode não usar DI em alguns casos?

  • Diminuição do número de aulas
  • Não criação de interfaces desnecessárias
  • Sem risco de bugs de incompatibilidade

Embora o módulo de catálogo Core tenha sido usado como auxiliar, ele usou DI extensivamente.Em minha pesquisa, descobri que o Magento 2 usava poucas funções nos arquivos auxiliares do Core Catalog que não são adequados para contratos de serviço.

Se você precisar usar explicitamente uma classe definida pelo Magento (como \Magento\Catalog\Model\Product), torne explícita a dependência implícita dependendo da implementação concreta em vez da interface do contrato de serviço.

Sem dúvida, o desenvolvedor de extensões deveria 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a magento.stackexchange
scroll top