Question

Quand je pense que j'ai la tête tournée vers le système DI de Magento 2, quelque chose apparaît et le déballe.
Je vois dans le code principal différentes manières d'accéder à un assistant.
Par exemple dans Magento\Catalog\Controller\Category::_initCategory il y a ça :

if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
    return false;
}

Mais en Magento\Catalog\Block\Category\View l'assistant est injecté dans le constructeur

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Model\Layer\Category $catalogLayer,
    \Magento\Framework\Registry $registry,
    \Magento\Catalog\Helper\Category $categoryHelper,
    array $data = array()
) {
    $this->_categoryHelper = $categoryHelper;
    $this->_catalogLayer = $catalogLayer;
    $this->_coreRegistry = $registry;
    parent::__construct($context, $data);
}

Cela m'a amené à penser que les assistants devraient être accessibles différemment dans les contrôleurs et les blocs (et les modèles), mais j'ai ensuite trouvé un contrôleur dans lequel un assistant est injecté dans le constructeur. Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute.

S'il vous plaît, dissiper le brouillard pour moi.
Quand dois-je utiliser DI et quand dois-je utiliser objectManager?et pourquoi?
J'ai lu cette question : Instanciation des assistants dans Magento 2.C'est juste une question complémentaire à ce sujet.

Était-ce utile?

La solution

Je préférerais DI lorsque cela est possible, car l'utilisation du gestionnaire d'objets est déjà une violation de la loi de Déméter.Lors de l'utilisation du gestionnaire d'objets, ces dépendances sont simplement masquées dans la logique de la méthode.

Autres conseils

Je ne sais pas grand-chose sur l'implémentation de Magento, mais il semble que le ObjectManager est un Localisateur de services.

Généralement, utiliser un localisateur de services pour accéder aux dépendances d'un objet est plutôt mauvais, passez à la caisse Cet article.

Définir explicitement vos dépendances via un constructeur est une bien meilleure approche.Cela aide à résoudre les tests unitaires et les problèmes de temps d'exécution lorsque les services ne sont pas définis.

Injecter le gestionnaire d'objets dans une classe revient essentiellement à injecter un registre dans votre classe qui a accès à tous vos services d'applications, ce qui n'est évidemment pas correct.

j'utilise ZF2 un peu et définissent généralement de petites classes d'usine pour les services, les contrôleurs et toute classe nécessitant des dépendances.Ces classes d'usine ont accès au localisateur de services, récupèrent tous les services dont dépend l'objet et les injectent via le constructeur.Utiliser un localisateur de services dans une classe Factory est très bien car il s'agit principalement de code jetable, quelque chose comme ce Par exemple.

Ces usines sont encore faciles à test.

OMI, utilisez l'injection de constructeur dans la mesure du possible.Encore une fois, je ne sais pas grand-chose sur l'implémentation de Magento et s'il a le concept de Factories, d'un rapide coup d'œil, il semble qu'il les prend en charge, mais définir explicitement vos classes et utiliser un localisateur de services pour les construire dans les classes Factory est une approche beaucoup plus propre.

Ceci vient de quelqu'un qui a une exposition limitée aux modèles mentionnés ci-dessus, j'aimerais donc également entendre les réflexions/expériences des autres sur le sujet !

Plus de lecture

Une autre façon d'utiliser l'assistant (dans les modèles) est :

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]')->getMethodName();

J'espère que cela vous sera utile si vous ne le saviez pas déjà.

Même si c'est une vieille question, je ne sais pas si Marius a eu sa réponse.Je crois Marius peux mieux y répondre.Je voudrais y répondre brièvement.Pourquoi Magento 2 suggère d'utiliser DI au lieu de helper ?

  • Rendre l'isolement dans les tests unitaires possible/facile
  • Définir explicitement les dépendances d'une classe
  • Faciliter une bonne conception (principe de responsabilité unique (SRP) par exemple)
  • L'utilisation de DI dans votre module réduit le risque de bogues d'incompatibilité lorsque Magento modifie la mise en œuvre sous-jacente de ces interfaces.Il s'agit d'un concept important à comprendre pour les développeurs d'extensions.

Pourquoi le noyau M2 pourrait ne pas utiliser DI dans certains cas ?

  • Nombre de classes en baisse
  • Ne pas créer d'interfaces inutiles
  • Aucun risque de bugs d'incompatibilité

Bien que le module de catalogue principal ait été utilisé comme assistant, il a largement utilisé DI.Dans mes recherches, j'ai découvert que Magento 2 utilisait peu de fonctions dans les fichiers d'assistance du Core Catalog qui ne conviennent pas aux contrats de service.

Si vous devez utiliser explicitement une classe définie par Magento (telle que \Magento\Catalog\Model\Product), rendez la dépendance implicite explicite en fonction de l'implémentation concrète au lieu de l'interface du contrat de service.

Sans aucun doute, le développeur d’extensions devrait utiliser DI au lieu de Magento1 comme Helper.Lors d’une mise en œuvre conformément aux directives de Magento 2, les retombées sont limitées.En cas de non-respect des recommandations, des problèmes surviennent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top