O que desencadeia a geração de uma fábrica no Magento 2

39

O Magento 2 contém vários arquivos de classe que são pré-gerados ou são gerados em tempo real. Eles vivem em

var/generated

Esses arquivos gerados incluem classes de fábrica. A partir da documentação , entendo que um programador usa classes de fábrica para instanciar objetos "não injetáveis". Um objeto "não injetável" é um objeto que não pode ser adicionado via __constructorinjeção de dependência, geralmente porque requer entrada do usuário para instanciar.

O que não está claro na documentação é como o Magento 2 sabe que precisa gerar uma classe de fábrica. Este pouco

Se uma fábrica inexistente for encontrada pelo gerenciador de objetos no modo de tempo de execução ou compilador, o gerenciador de objetos gerará a fábrica.

faz parecer que se eu usar uma classe de fábrica no gerenciador de objetos (ou, por extensão, nos construtores de injeção de dependência), o Magento 2 a gerará para mim. Mas como o gerente de objetos sabe que o que estou solicitando é uma fábrica?

Além disso, parece haver dois comandos para gerar automaticamente (ou "compilar") todas as classes geradas. A execução de um desses comandos gera um grande número de classes Factory. Quais arquivos de configuração e / ou código esses comandos estão procurando para gerar os objetos de fábrica necessários?

Eu sei que rastrear o gerenciador de objetos e / ou o código de comando até o fim revelaria isso, mas espero evitar essa longa e árdua jornada.

Alan Storm
fonte

Respostas:

21

Uma localização de código interessante sobre como tudo isso funciona: https://github.com/magento/magento2/blob/develop/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php#L40

Com os diferentes tipos vindo principalmente daqui https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/ObjectManager/Code/Generator, mas também daqui https://github.com/magento / magento2 / tree / develop / lib / internal / Magento / Framework / Interception / Code / Generator para o código de interceptação.

Tudo é acionado pelo carregador automático aqui https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Code/Generator/Autoloader.php#L32

public function load($className)
{
    if (!class_exists($className)) {
        return Generator::GENERATION_ERROR != $this->_generator->generateClass($className);
    }
    return true;
}
Kristof na Fooman
fonte
9

Não encontrei no código as condições para as quais as fábricas são geradas, mas, pelo meu entendimento, uma classe de fábrica é gerada quando solicitada e não encontrada.
Existem algumas palavras-chave reservadas Factory, Proxy, Interceptor, se usadas, acionarão a geração de código quando as classes específicas não forem encontradas.
Vou postar de volta assim que encontrar o código que aciona a geração da fábrica.
Portanto, se você solicitar a classe Some\Namespace\HereFactorye a classe não existir, porque termina com a palavra Factory- chave, ela será gerada novar/generation/Some/Namespace/HereFactory.php

Marius
fonte
Parece que os documentos devem ser atualizados, pois o ObjectManager não é o único que está gerando. Carregador automático especial faz parte da resposta. github.com/magento/magento2/blob/develop/lib/internal/Magento/...
Chris O'Toole
11
Isso está de acordo com a minha experiência (consulte gist.github.com/astorm/f245ce9c761c9a8053aa), mas levanta a questão 1. Onde isso acontece no código do gerenciador de objetos (ou seja, qual é a convenção real) 2. Como o compilador / gerador sabe quais fábricas gerar?
Alan Storm
8

Estou cavando nesta mesma sopa de ervilha agora. Até agora, meu entendimento é que todo o material gerado automaticamente /var/generationé feito a partir das preferências e interfaces declaradas em app/etc/di.xml.

Interfaces e preferências suas serão declaradas no di.xmlarquivo no seu /app/code/Vendor/<module>/etc/di.xml.

Ele sabe gerar o (s) objeto (s) para você porque você declarou uma interface no seu __constructorAND e declarou uma preferência por essa interface global ou localmente no di.xmlarquivo apropriado .

Ofereço três grãos de sal com meus comentários.

Dave G
fonte
+1 para obter informações úteis - mas parece que as Fábricas vêm de outro lugar que não os di.xmlarquivos - você pode enviar algo para o gerenciador de objetos que termina no Factory e ele gera um arquivo para você.
Alan Storm
Isso ajuda? bit.ly/1BOtdie
Steve Johnson