In che modo Magento2 genera la specifica estensione di estensione ed estensione interfaccia?
-
19-12-2019 - |
Domanda
Vorrei avvolgere la mia testa usando gli attributi di estensione, ad esempio per gli elementi di quotazione.
Non è un problema aggiungendo un attributo personalizzato a tale entità utilizzando una classe di configurazione come in Magento 1, questo non è ciò che è questa domanda.
Al momento la magia mi travolge quando voglio esporre tale attributo aggiunto da un'estensione tramite l'API delle entità come attributo di estensione.
Aggiornamento : So come vengono generate le fabbriche regolari. Questa domanda riguarda le fabbriche speciali che istanziare le implementazioni generate per le interfacce di attributi di estensione generate.
Ecco i passi che prendo per farlo funzionare. Sto aggiungendo questi così chiunque tenta di rispondere non ha bisogno di entrare in quei dettagli.
La mia domanda è Come o Perché funziona.
Passi per l'esposizione di un attributo di estensione tramite un'API di entità:
- .
- Crea un
etc/extension_attributes.xml
che aggiunge l'attributo all'interfaccia di entità - Creare un plugin per aggiungere il valore dell'attributo alle entità
ExtensionAttributes
istance.
Per effettuare il secondo punto, è necessaria l'istanza delle entità ExtensionAttributes
. Per questo motivo il plugin dipende da una fabbrica, che il manager dell'oggetto fornisce via di.
Per l'elemento di preventivo Esempio Magento\Quote\Api\Data\CartItemExtensionFactory
deve essere utilizzato.
Immagino che il tipo di questa fabbrica in qualche modo debba essere il trigger per la magia della generazione.
Magento genera quindi l'interfaccia corrispondente \Magento\Quote\Api\Data\CartItemExtensionInterface
con i setter e i getter per tutti gli attributi di estensione.
Tuttavia, non sembra generare l'implementazione concreta per quell'interfaccia. A locazione Phpstorm non lo sta vedendo.
In che modo Magento raccoglie le informazioni necessarie per generare la classe? Come possono essere chiamati i metodi di interfaccia generati su un'istanza concreta? È una classe che viene generata solo in memoria solo?
Sono felice che funziona, ma non è davvero soddisfacente. Capacità di Magentos di utilizzare gli attributi creati automaticamente dalle estensioni è un fattore chiave per il suo successo. Come sviluppatore di moduli, credo di aver bisogno di una comprensione approfondita dell'intero processo.
Dovrei avere tempo lo avrei semplicemente scavato in questo stesso, ma preferirei se potessi solo ottenere una spiegazione.
Aggiornamento 2 : Ci sono voluti un po 'di tempo per leggere \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
e \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
. Ora ho almeno un'idea approssimativa su cosa sta succedendo. Se nessuno mi batte, scriverò una descrizione del processo completo a un certo punto, come penso che sarebbe un utile riferimento.
Soluzione
Prima di tutto l'autogenerazione sta accadendo in base al suffisso del nome della classe, ad es. Factory
, ExtensionInterface
(vedere \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX
) o Extension
(vedere \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX
).
Generatore corretto è selezionato in base al suffisso qui \Magento\Framework\Code\Generator::generateClass
.
Assumere la modalità Magento è developer
e le classi mancanti possono essere generate sul volo (il processo simile avverrà quando viene utilizzato il compilatore). Quando Object Manager cerca di istanziare Diciamo Magento\Quote\Api\Data\CartItemExtensionFactory
e non esiste, succede quanto segue:
- .
- Autoloader non riesce a istanziare la classe e inizia la generazione del codice qui
\Magento\Framework\Code\Generator\Autoloader::load
- Quindi il suffisso di classe è determinato come
Factory
(elenco di tutti i suffissi dichiarati è possibile trovare qui\Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator
) e la corrispondente classe del generatore di fabbrica (Magento\Framework\ObjectManager\Code\Generator\Factory
) viene utilizzato per generare fabbrica mancante - Tutte le classi autogenerate sono sempre basate su altre classi, in caso di fabbrica, il nome della classe di origine è calcolato semplicemente rimuovendo il suffisso
Factory
, saràMagento\Quote\Api\Data\CartItemExtension
. Questa classe non esiste e l'autogenerizzazione viene richiamata ancora una volta per autoloader, ma questa volta per la classe di estensione - Ora suffisso è
Extension
e\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
verranno utilizzati per generare questa classe - Classe di origine per la generazione di classe di estensione viene calcolata come
Magento\Quote\Api\Data\CartItemInterface
, esiste e la classe di estensione viene generata con successo. Tuttavia, nel tentativo di includere il file di classe di estensione, l'autogenerazione viene attivata ancora una volta perchéMagento\Quote\Api\Data\CartItemExtension
implementaMagento\Quote\Api\Data\CartItemExtensionInterface
, che non esiste - Suffisso è
ExtensionInterface
e\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
verranno utilizzati per la generazione - Prolungainterface e lezioni di estensione sono generate in base alle informazioni da
extension_attributes.xml
, accessibili tramite\Magento\Framework\Api\ExtensionAttribute\Config
, quindi viene generata la fabbrica
Una nota importante è che non vi è alcuna preferenza per estensione interfaccia in generatori in generazione in generazione in quanto sia estensione che estensione interfaccia automatica. Questo non è un problema perché non dovrebbe essere iniettato direttamente la costruzione.
Altri suggerimenti
Per me, stasera, in cima alla risposta da @alex, posso vedere le linee
$modelReflection = new \ReflectionClass($extensibleClassName);
if ($modelReflection->isInterface()
&& $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
&& $modelReflection->hasMethod('getExtensionAttributes')
) {
$this->classInterfaceMap[$extensibleClassName] = $extensibleClassName;
return $this->classInterfaceMap[$extensibleClassName];
}
.
Nella classe \Magento\Framework\Api\ExtensionAttributesFactory
sono dove potremmo voler iniziare il debug se l'interfaccia di estensione non viene generata.Attributi praticamente di estensione riguardano strutturare la nostra classe come Magento 2 si aspetterà.
Queste linee stanno dicendo:
- .
-
è la classe nella nostra estensione_attributi un'interfaccia
-
si estende \ magento \ framework \ API \ ExtensibleDatainterFace
-
ha questa interfaccia una funzione chiamata GetExtensionattributes