Was löst die Erzeugung einer Fabrik in Magento 2

39

Magento 2 enthält eine Reihe von Klassendateien, die entweder vorgeneriert oder sofort generiert werden. Sie leben in

var/generated

Diese generierten Dateien enthalten Factory-Klassen. Aus der Dokumentation geht hervor, dass ein Programmierer Factory-Klassen verwendet, um "nicht injizierbare" Objekte zu instanziieren. Ein "nicht injizierbares" Objekt ist ein Objekt, das nicht über die __constructorAbhängigkeitsinjektion hinzugefügt werden kann , da für die Instanziierung normalerweise Benutzereingaben erforderlich sind.

Aus der Dokumentation geht nicht hervor, wie Magento 2 weiß, dass es eine Factory-Klasse erzeugen muss. Dieses bisschen

Wenn der Objektmanager im Laufzeitmodus oder im Compiler auf eine nicht vorhandene Factory stößt, generiert der Objektmanager die Factory.

klingt so, als ob ich eine Factory-Klasse im Objekt-Manager (oder, im weiteren Sinne, in den Abhängigkeitsinjektions-Konstruktoren) verwende, die von Magento 2 für mich generiert wird. Aber woher weiß der Objektmanager, dass das, was ich anfordere, eine Fabrik ist?

Es scheint auch zwei Befehle zu geben, um alle generierten Klassen automatisch zu generieren (oder zu "kompilieren"). Wenn Sie einen dieser Befehle ausführen, wird eine große Anzahl von Factory-Klassen generiert. Welche Konfigurations- und / oder Codedateien betrachten diese Befehle, um die erforderlichen Factory-Objekte zu generieren?

Ich weiß, dass eine vollständige Verfolgung des Objektmanagers und / oder des Befehlscodes dies aufdecken würde, aber ich hoffe, diese lange und mühsame Reise zu vermeiden.

Alan Storm
quelle

Antworten:

21

Einige interessante Code-Speicherorte für das Zusammenspiel: https://github.com/magento/magento2/blob/develop/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php#L40

Die verschiedenen Typen kommen meist von hier https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/ObjectManager/Code/Generator aber auch von hier https://github.com/magento / magento2 / tree / develop / lib / internal / Magento / Framework / Interception / Code / Generator für den Interception-Code.

Alles wird vom Autoloader hier ausgelöst: 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 bei Fooman
quelle
9

Ich habe im Code nicht gefunden, für welche Bedingungen die Fabriken generiert werden, aber nach meinem Verständnis wird eine Factory-Klasse generiert, wenn sie angefordert und nicht gefunden wird.
Bei Verwendung einiger reservierter Schlüsselwörter Factory, Proxy, Interceptorwird die Codegenerierung ausgelöst, wenn die bestimmten Klassen nicht gefunden werden.
Ich werde zurückschreiben, sobald ich den Code finde, der die Factory-Generation auslöst.
Wenn Sie also die Klasse anfordern, Some\Namespace\HereFactoryexistiert sie nicht, da sie mit dem Schlüsselwort endet Factory, das in der generiert wirdvar/generation/Some/Namespace/HereFactory.php

Marius
quelle
Es sieht so aus, als ob Dokumente aktualisiert werden sollten, da der ObjectManager nicht wirklich derjenige ist, der sie generiert. Ein spezieller Autolader ist Teil der Antwort. github.com/magento/magento2/blob/develop/lib/internal/Magento/…
Chris O'Toole
1
Dies stimmt mit meiner Erfahrung überein (siehe gist.github.com/astorm/f245ce9c761c9a8053aa), wirft jedoch die Frage auf: 1. Wo geschieht dies im Objektmanager-Code (dh wie lautet die aktuelle Konvention)? 2. Wie funktioniert der Compiler / Generator wissen, welche Fabriken zu generieren?
Alan Storm
8

Ich grabe gerade in der gleichen Erbsensuppe. Mein bisheriges Verständnis ist, dass alles, was automatisch generiert /var/generationwird, über die in deklarierten Einstellungen und Schnittstellen erfolgt app/etc/di.xml.

Ihre Schnittstellen und Einstellungen werden in der di.xmlDatei in Ihrer deklariert /app/code/Vendor/<module>/etc/di.xml.

Es kann die Objekte für Sie generieren, da Sie in Ihrem __constructorAND eine Schnittstelle deklariert haben und in der entsprechenden di.xmlDatei eine Präferenz für diese Schnittstelle entweder global oder lokal deklariert haben .

Ich biete drei Körner Salz mit meinen Kommentaren an.

Dave G
quelle
+1 für nützliche Informationen - aber es di.xmlsieht so aus, als ob Fabriken von einem anderen Ort als den Dateien stammen - Sie können etwas an den Objektmanager senden, der in Factory endet, und es wird eine Datei für Sie generiert.
Alan Storm
Hilft das? bit.ly/1BOtdie
Steve Johnson