Wie generiert Magento2 die spezifische ExtensionFactory und ExtensionAttributeInterface?


28

Ich möchte meinen Kopf mit Erweiterungsattributen, zum Beispiel für Angebotselemente, umschließen.
Es ist kein Problem, mit einer Setup-Klasse wie in Magento 1 ein benutzerdefiniertes Attribut zu einer solchen Entität hinzuzufügen. Darum geht es in dieser Frage nicht.
Im Moment überwältigt mich die Magie, wenn ich ein solches Attribut, das von einer Erweiterung über die Entities-API hinzugefügt wurde, als Erweiterungsattribut verfügbar machen möchte.

UPDATE : Ich weiß, wie die regulären Fabriken entstehen. Diese Frage bezieht sich auf die speziellen Factorys, die die generierten Implementierungen für die generierten Erweiterungsattributschnittstellen instanziieren.

Hier sind die Schritte, die ich unternehme, um es zum Laufen zu bringen. Ich füge diese hinzu, damit jeder, der versucht zu antworten, nicht auf diese Details eingehen muss.
Meine Frage ist WIE oder warum es funktioniert.

Schritte zum Anzeigen eines Erweiterungsattributs über eine Entitäts-API:

  1. Erstellen Sie eine etc/extension_attributes.xml, die das Attribut zur Entitätsschnittstelle hinzufügt
  2. Erstellen Sie ein Plugin, um den Attributwert der Entitätsinstanz hinzuzufügen ExtensionAttributes.

Um den zweiten Punkt ausführen zu können, wird die ExtensionAttributesInstanz des Entities benötigt. Aus diesem Grund ist das Plugin von einer Factory abhängig, die der Objektmanager über DI bereitstellt.

Für das Angebot muss ein Artikelbeispiel Magento\Quote\Api\Data\CartItemExtensionFactoryverwendet werden.
Ich denke, die Art dieser Fabrik muss der Auslöser für die Generationszauber sein.

Magento generiert dann \Magento\Quote\Api\Data\CartItemExtensionInterfacefür alle Erweiterungsattribute die passende Schnittstelle mit den Setters und Getters.
Es scheint jedoch nicht die konkrete Implementierung für diese Schnittstelle zu generieren. Mindestens PHPStorm sieht es nicht.

Wie sammelt Magento die Informationen, die es zum Generieren der Klasse benötigt? Wie können die generierten Schnittstellenmethoden auf einer konkreten Instanz aufgerufen werden? Ist es eine Klasse, die nur im Speicher generiert wird?

Ich bin froh, dass es funktioniert, aber das ist nicht wirklich befriedigend. Die Fähigkeit von Magentos, von Erweiterungen automatisch erstellte Attribute zu verwenden, ist ein Schlüsselfaktor für den Erfolg. Als Modulentwickler glaube ich, dass ich ein gründliches Verständnis des gesamten Prozesses brauche.
Sollte ich Zeit haben, würde ich mich selbst damit befassen, aber ich würde es vorziehen, wenn ich nur eine Erklärung bekommen könnte.

UPDATE 2 : Nahm ein wenig Zeit zum Lesen durch \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratorund \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator. Jetzt habe ich zumindest eine ungefähre Vorstellung davon, was los ist. Wenn mich niemand schlägt, schreibe ich an einer Stelle eine Beschreibung des gesamten Vorgangs, da ich denke, dass dies eine nützliche Referenz wäre.


2
Habe der Vinai .. die Frage gestellt ..Omg
Amit Bera

Antworten:


26

Vor allem automatischen Generierung geschieht basierend auf Klassennamen Suffix, zB Factory, ExtensionInterface(siehe \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX) oder Extension(siehe \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX).

Der richtige Generator wird hier basierend auf dem Suffix ausgewählt \Magento\Framework\Code\Generator::generateClass.

Nehmen wir an, der Magento-Modus ist developerund fehlende Klassen können im laufenden Betrieb generiert werden (ähnlicher Vorgang wird bei Verwendung des Compilers auftreten). Wenn der Objektmanager versucht zu instanziieren Magento\Quote\Api\Data\CartItemExtensionFactoryund dies nicht der Fall ist, geschieht Folgendes:

  1. Autoloader kann die Klasse nicht instanziieren und initiiert hier die Codegenerierung \Magento\Framework\Code\Generator\Autoloader::load
  2. Dann wird das Klassensuffix bestimmt als Factory(Liste aller deklarierten Suffixe finden Sie hier \Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator) und die entsprechende Factory-Generator-Klasse ( Magento\Framework\ObjectManager\Code\Generator\Factory) wird verwendet, um eine fehlende Factory zu generieren
  3. Alle automatisch generierten Klassen basieren immer auf anderen Klassen. Im Falle einer Fabrik wird der Name der Quellklasse nur durch Entfernen des FactorySuffix berechnet Magento\Quote\Api\Data\CartItemExtension. Diese Klasse existiert nicht und die automatische Generierung wird vom Autoloader erneut aufgerufen, diesmal jedoch für die Extension-Klasse
  4. Jetzt wird Extensionund \Magento\Framework\Api\Code\Generator\ExtensionAttributesGeneratorwird das Suffix verwendet, um diese Klasse zu generieren
  5. Die Quellklasse für die Generierung der Erweiterungsklasse wird so berechnet, wie Magento\Quote\Api\Data\CartItemInterfacesie vorhanden ist und die Erweiterungsklasse erfolgreich generiert wurde. Beim Versuch, eine Erweiterungsklassendatei einzuschließen, wird die automatische Generierung jedoch erneut ausgelöst, da nicht vorhandene Magento\Quote\Api\Data\CartItemExtensionGeräte Magento\Quote\Api\Data\CartItemExtensionInterfacevorhanden sind
  6. Suffix ist ExtensionInterfaceund \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratorwird für die Generierung verwendet
  7. ExtensionInterface- und Extension-Klassen werden auf der Grundlage von Informationen generiert, auf extension_attributes.xmldie über zugegriffen werden \Magento\Framework\Api\ExtensionAttribute\Configkann. Anschließend wird Factory generiert

Ein wichtiger Hinweis ist, dass ExtensionInterface in nicht bevorzugt wird, di.xmlda Extension und ExtensionInterface automatisch generiert werden. Dies ist kein Problem, da nicht erwartet wird, dass ExtentionInterface direkt über das Konstrukt injiziert wird.


@ Vinai du bist willkommen. Bounty war eine schöne Überraschung, danke. Update: Nur zu Ihrer Information, wenn die Prämie gestartet wurde, nachdem die Antwort akzeptiert wurde, wird sie nicht automatisch vergeben.
Alex Paliarush

0

Für mich, heute Abend, kann ich zusätzlich zu der Antwort von @Alex die Zeilen sehen

$modelReflection = new \ReflectionClass($extensibleClassName);
        if ($modelReflection->isInterface()
            && $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
            && $modelReflection->hasMethod('getExtensionAttributes')
        ) {
            $this->classInterfaceMap[$extensibleClassName] = $extensibleClassName;
            return $this->classInterfaceMap[$extensibleClassName];
        }

in der Klasse \Magento\Framework\Api\ExtensionAttributesFactory

Hier können Sie mit dem Debuggen beginnen, wenn die Erweiterungsschnittstelle nicht generiert wird. Bei so ziemlich den Erweiterungsattributen geht es um die Strukturierung unserer Klasse, wie es Magento 2 erwartet.

Diese Zeilen sagen:

  • ist die Klasse in unseren extension_attributes eine Schnittstelle

  • Erweitert es \ Magento \ Framework \ Api \ ExtensibleDataInterface

  • hat diese Schnittstelle eine Funktion namens getExtensionAttributes

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.