Qu'est-ce qui déclenche la génération d'une usine dans Magento 2

39

Magento 2 contient un certain nombre de fichiers de classe pré-générés ou générés à la volée. Ils vivent dans

var/generated

Ces fichiers générés incluent les classes d'usine. D'après ma documentation , un programmeur utilise des classes d'usine pour instancier des objets "non injectables". Un objet "non injectable" est un objet qui ne peut pas être ajouté via __constructorune injection de dépendance, généralement parce qu'il nécessite une entrée utilisateur pour instancier.

Ce qui n’est pas clair dans la documentation, c’est que Magento 2 sait qu’il doit générer une classe fabrique. Ce bit

Si le gestionnaire d’objets rencontre une fabrique inexistante en mode d’exécution ou un compilateur, le gestionnaire d’objets génère la fabrique.

donne l'impression que, si j'utilise une classe de fabrique dans le gestionnaire d'objets (ou, par extension, dans les dépendances d'injection de dépendances __), Magento 2 le générera pour moi. Mais comment le gestionnaire d'objets sait-il que ce que je demande est une usine?

En outre, il semble y avoir deux commandes pour générer automatiquement (ou "compiler") toutes les classes générées. L'exécution de l'une de ces commandes génère un grand nombre de classes Factory. Quels sont les fichiers de configuration et / ou de code utilisés par ces commandes pour générer les objets d'usine nécessaires?

Je sais que le traçage du gestionnaire d’objets et / ou du code de commande jusqu’au bout l’indiquerait, mais j’espère pouvoir éviter ce long et pénible voyage.

Alan Storm
la source

Réponses:

21

Voici un emplacement de code intéressant pour savoir comment cela fonctionne: https://github.com/magento/magento2/blob/develop/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php#L40

Avec les différents types venant principalement d’ici https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/ObjectManager/Code/Generator mais également d’ici https://github.com/magento / magento2 / tree / develop / lib / internal / Magento / Framework / Interception / Code / Generator pour le code d'interception.

Tout est déclenché par l'autochargeur ici 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 chez Fooman
la source
9

Je n'ai pas trouvé dans le code les conditions pour lesquelles les usines sont générées, mais si je comprends bien, une classe d'usine est générée lorsqu'elle est demandée et non trouvée.
Certains mots Factory, Proxy, Interceptor- clés réservés , s’ils sont utilisés, vont déclencher la génération de code lorsque les classes spécifiques ne sont pas trouvées.
Je posterai dès que je trouverai le code qui déclenche la génération d'usine.
Donc, si vous demandez la classe Some\Namespace\HereFactoryet que celle-ci n’existe pas, elle se termine par le mot-clé Factoryqui sera généré dans levar/generation/Some/Namespace/HereFactory.php

Marius
la source
On dirait que les documents doivent être mis à jour car ObjectManager n'est pas vraiment celui qui génère. Un chargeur automatique spécial fait partie de la réponse. github.com/magento/magento2/blob/develop/lib/internal/Magento/…
Chris O'Toole
1
Cela correspond à mon expérience (voir gist.github.com/astorm/f245ce9c761c9a8053aa), mais cela soulève la question 1. Où cela se produit-il dans le code du gestionnaire d'objets (c'est-à-dire quelle est la convention réelle) 2. Comment le compilateur / Le générateur sait-il quelles usines générer?
Alan Storm
8

Je suis en train de creuser dans cette même soupe aux pois en ce moment. D'après ce que j'ai compris jusqu'à présent, tout ce qui est généré automatiquement à /var/generationpartir des préférences et des interfaces déclarées dans app/etc/di.xml.

di.xmlVos interfaces et vos préférences vont être déclarées dans le fichier dans votre /app/code/Vendor/<module>/etc/di.xml.

Il sait générer le ou les objets pour vous car vous avez déclaré une interface dans votre __constructorAND et déclaré une préférence pour cette interface, globalement ou localement, dans le di.xmlfichier approprié .

Je propose trois grains de sel avec mes commentaires.

Dave G
la source
+1 pour les informations utiles - mais il semble que les usines viennent d'un autre endroit que les di.xmlfichiers - vous pouvez envoyer quelque chose dans le gestionnaire d'objets qui se termine par Factory et il va générer un fichier pour vous.
Alan Storm
est-ce que cela aide? bit.ly/1BOtdie
Steve Johnson