Lo que desencadena la generación de una fábrica en Magento 2

39

Magento 2 contiene una serie de archivos de clase que se generan previamente o se generan sobre la marcha. Viven en

var/generated

Estos archivos generados incluyen clases de fábrica. De la documentación , entiendo que un programador usa clases de fábrica para crear instancias de objetos "no inyectables". Un objeto "no inyectable" es un objeto que no se puede agregar mediante __constructorinyección de dependencia, generalmente porque requiere la entrada del usuario para crear una instancia.

Lo que no está claro en la documentación es cómo Magento 2 sabe que necesita generar una clase de fábrica. Esta parte

Si el administrador de objetos encuentra una fábrica inexistente en modo de ejecución o compilador, el administrador de objetos genera la fábrica.

suena como si uso una clase de fábrica en el administrador de objetos (o, por extensión, en la inyección de dependencia __constructores), que Magento 2 lo generará para mí. Pero, ¿cómo sabe el administrador de objetos que lo que solicito es una fábrica?

Además, parece haber dos comandos para generar automáticamente (o "compilar") todas las clases generadas. La ejecución de cualquiera de estos comandos genera una gran cantidad de clases Factory. ¿Qué archivos de configuración y / o código están buscando estos comandos para generar los objetos de fábrica necesarios?

Sé que rastrear el administrador de objetos y / o el código de comando hasta el final revelaría esto, pero espero evitar ese largo y arduo viaje.

Alan Storm
fuente

Respuestas:

21

Una ubicación de código interesante sobre cómo funciona todo esto junto: https://github.com/magento/magento2/blob/develop/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php#L40

Con los diferentes tipos procedentes principalmente de aquí https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/ObjectManager/Code/Generator pero también desde aquí https://github.com/magento / magento2 / tree / development / lib / internal / Magento / Framework / Interception / Code / Generator para el código de intercepción.

Todo se activa por el cargador automático aquí 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 en Fooman
fuente
9

No he encontrado en el código, las condiciones para las que se generan las fábricas, pero, según tengo entendido, se genera una clase de fábrica cuando se solicita y no se encuentra. Si se usan
algunas palabras clave reservadas Factory, Proxy, Interceptor, se activará la generación de código cuando no se encuentren las clases específicas.
Volveré a publicar tan pronto como encuentre el código que desencadena la generación de fábrica.
Entonces, si solicita la clase Some\Namespace\HereFactoryy la clase no existe, porque termina con la palabra clave Factory, se generará en elvar/generation/Some/Namespace/HereFactory.php

Marius
fuente
Parece que los documentos deberían actualizarse, ya que ObjectManager no es realmente el que genera. El cargador automático especial es parte de la respuesta. github.com/magento/magento2/blob/develop/lib/internal/Magento/…
Chris O'Toole
1
Eso se alinea con mi experiencia (ver gist.github.com/astorm/f245ce9c761c9a8053aa), pero plantea la pregunta 1. ¿Dónde sucede esto en el código del administrador de objetos (es decir, cuál es la convención real) 2. Cómo funciona el compilador / generador sabe qué fábricas generar?
Alan Storm
8

Estoy cavando en esta misma sopa de guisantes en este momento. Hasta ahora, entiendo que todo lo que se genera automáticamente /var/generationse realiza a partir de las preferencias y las interfaces declaradas en app/etc/di.xml.

Las interfaces y preferencias suyas se declararán en el di.xmlarchivo en su /app/code/Vendor/<module>/etc/di.xml.

Sabe generar el (los) objeto (s) por usted porque ha declarado una interfaz en su __constructorAND y ha declarado una preferencia por esa interfaz global o localmente en el di.xmlarchivo apropiado .

Ofrezco tres granos de sal con mis comentarios.

Dave G
fuente
+1 para la información útil, pero parece que las Fábricas provienen de otro lugar que no sean los di.xmlarchivos, puede enviar algo al administrador de objetos que termina en Factory y generará un archivo para usted.
Alan Storm
¿Esto ayuda? bit.ly/1BOtdie
Steve Johnson