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à:

    .
  1. Crea un etc/extension_attributes.xml che aggiunge l'attributo all'interfaccia di entità
  2. Creare un plugin per aggiungere il valore dell'attributo alle entità ExtensionAttributes istance.
  3. 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.

È stato utile?

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:

    .
  1. Autoloader non riesce a istanziare la classe e inizia la generazione del codice qui \Magento\Framework\Code\Generator\Autoloader::load
  2. 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
  3. 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
  4. Ora suffisso è Extension e \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator verranno utilizzati per generare questa classe
  5. 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 implementa Magento\Quote\Api\Data\CartItemExtensionInterface, che non esiste
  6. Suffisso è ExtensionInterface e \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator verranno utilizzati per la generazione
  7. 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
  8. 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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top