Comment Magento2 générer spécifiques ExtensionFactory et ExtensionAttributeInterface?
-
19-12-2019 - |
Question
Je tiens à envelopper ma tête autour de l'utilisation des attributs d'extension, par exemple pour citer les éléments.
Il n'est pas un problème en ajoutant un attribut personnalisé à une telle entité à l'aide d'une installation de classe comme dans Magento 1, ce n'est pas ce que cette question est à propos.
Au moment où la magie me submerge quand je veux exposer un tel attribut qui a été ajouté par une extension via les entités de l'API comme une extension de l'attribut.
Mise à JOUR: Je sais comment les usines habituelles sont générés.Cette question est à propos des usines spéciales instancie le générés de construction pour l'extension générée attribut interfaces.
Voici les mesures que je prends pour le faire fonctionner.Je suis l'ajout de ces donc, quiconque tente de répondre n'a pas besoin d'aller dans ces détails.
Ma question est COMMENT ou POURQUOI elle fonctionne.
Les étapes pour une exposition d'un attribut d'extension via une entité de l'API:
- Créer un
etc/extension_attributes.xml
qui ajoute l'attribut de l'entité de l'interface - Créer un plugin pour ajouter la valeur de l'attribut pour les entités
ExtensionAttributes
exemple.
Pour le deuxième point, les entités ExtensionAttributes
exemple est nécessaire.Pour cette raison, le plugin dépend d'une usine, dont le gestionnaire d'objets, de fournitures via DI.
Pour la citation de l'élément de exemple Magento\Quote\Api\Data\CartItemExtensionFactory
doit être utilisé.
Je suppose que le type de cette usine doit en quelque sorte être le déclencheur de la génération de la magie.
Magento génère alors le correspondant de l'interface \Magento\Quote\Api\Data\CartItemExtensionInterface
avec les setters et getters pour tous les attributs d'extension.
Cependant, il ne semble pas générer de la mise en œuvre concrète de cette interface.À bail PHPStorm n'est pas de le voir.
Comment Magento recueillir les informations dont il a besoin pour générer la classe?Comment peut-généré à l'interface des méthodes d'être appelé sur un exemple concret?C'est une classe qui obtient juste générés dans la mémoire?
Je suis content que ça fonctionne, mais ce n'est pas vraiment satisfaisant.Magentos capacité à utiliser des attributs créés automatiquement par des extensions est un facteur clé de son succès.En tant que développeur de modules, je crois que j'ai besoin d'une compréhension approfondie de l'ensemble du processus.
Si j'ai le temps je venais de creuser en moi-même, mais je préfère que si je ne pouvais tout simplement obtenir une explication.
Mise à JOUR 2:Pris un peu de temps pour lire \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
et \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
.Maintenant, j'ai au moins une idée approximative de ce qui se passe.Si personne ne me bat pour elle, je vais écrire une description de l'ensemble du processus à un moment donné, comme je pense qu'il serait utile de référence.
La solution
Tout d'abord autogeneration qui se passe en fonction de la classe de suffixe de nom, par exemple Factory
, ExtensionInterface
(voir \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX
) ou Extension
(voir \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX
).
Bon générateur est sélectionné sur la base suffixe ici \Magento\Framework\Code\Generator::generateClass
.
Supposons Magento mode est developer
et les classes manquantes peuvent être générés à la volée (processus similaire se produira lorsque le compilateur est utilisé).Lorsque le gestionnaire d'objets essaie d'instancier disons Magento\Quote\Api\Data\CartItemExtensionFactory
et il n'existe pas, le suivant se produit:
- Autochargeur ne parvient pas à instancier la classe et lance la génération de code ici
\Magento\Framework\Code\Generator\Autoloader::load
- Puis suffixe de classe est déterminé comme
Factory
(liste de déclarer tous les suffixes peuvent être trouvés ici\Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator
) et de l'Usine de générateur de classe (Magento\Framework\ObjectManager\Code\Generator\Factory
) est utilisé pour générer manque d'usine - Tous générée automatiquement les classes sont toujours basées sur un autre classes, dans le cas de l'usine, de source nom de la classe est calculée par simple suppression
Factory
suffixe, il seraMagento\Quote\Api\Data\CartItemExtension
.Cette classe n'existe pas et autogeneration est invoquée une fois de plus par l'autochargeur, mais cette fois pour la classe d'Extension - Maintenant suffixe est
Extension
et\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
sera utilisé pour générer cette classe - Source de la classe de l'Extension de génération de classe est calculé comme
Magento\Quote\Api\Data\CartItemInterface
, il existe et l'Extension de la classe est générée avec succès.Cependant, sur la tentative d'inclure l'Extension de fichier de classe, autogeneration est déclenché une fois de plus, parce queMagento\Quote\Api\Data\CartItemExtension
met en œuvreMagento\Quote\Api\Data\CartItemExtensionInterface
, qui n'existe pas - Le suffixe est
ExtensionInterface
et\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
sera utilisé pour la génération - ExtensionInterface et classes d'Extension sont générés sur la base d'informations de
extension_attributes.xml
, accessible via\Magento\Framework\Api\ExtensionAttribute\Config
, puis l'Usine est généré
Une remarque importante est qu'il n'y a pas de préférence pour ExtensionInterface dans di.xml
parce que à la fois l'Extension et ExtensionInterface sont générés automatiquement.Ce n'est pas un problème parce que ExtentionInterface ne devrait pas être injecté par construire directement.
Autres conseils
Pour moi, ce soir, sur le haut de la réponse de @Alex, je peux voir les lignes
$modelReflection = new \ReflectionClass($extensibleClassName);
if ($modelReflection->isInterface()
&& $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
&& $modelReflection->hasMethod('getExtensionAttributes')
) {
$this->classInterfaceMap[$extensibleClassName] = $extensibleClassName;
return $this->classInterfaceMap[$extensibleClassName];
}
dans la classe \Magento\Framework\Api\ExtensionAttributesFactory
sont où l'on peut vouloir démarrer le débogage si l'extension de l'interface n'est pas généré.Assez bien les attributs d'extension est à propos de la structuration de notre classe comme Magento 2 va attendre.
ces lignes sont en train de dire:
c'est la classe dans notre extension_attributes une interface
il ne s'étend \Magento\Framework\Api\ExtensibleDataInterface
a cette interface une fonction appelée getExtensionAttributes