Frage

Wenn ich denke, dass ich meinen Kopf um das DI-System von Magento 2 gewickelt habe, kommt etwas auf und wickelt es ab.
Ich sehe im Kerncode verschiedene Möglichkeiten, auf einen Helfer zuzugreifen.
Zum Beispiel in Magento\Catalog\Controller\Category::_initCategory da ist das:

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

Aber in Magento\Catalog\Block\Category\View der Helfer wird in den Konstruktor injiziert

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);
}

Dies führte mich zu der Annahme, dass auf die Helfer in Controllern und Blöcken (und Modellen) unterschiedlich zugegriffen werden sollte, aber dann habe ich einen Controller gefunden, in den ein Helfer in den Konstruktor eingefügt wird Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute.

Bitte räumen Sie den Nebel für mich auf.
Wann sollte ich DI verwenden und wann sollte ich verwenden objectManager?und warum?
Ich habe diese Frage gelesen: Instanziieren von Helfern in Magento 2.Dies ist nur eine Folgefrage dazu.

War es hilfreich?

Lösung

Ich würde DI bevorzugen, wo es möglich ist, da die Verwendung des Objektmanagers bereits einen Verstoß gegen das Demeter-Gesetz darstellt.Bei Verwendung des Objektmanagers sind diese Abhängigkeiten nur in der Methodenlogik verborgen.

Andere Tipps

Ich weiß nicht so viel über die Magento-Implementierung, aber es sieht so aus ObjectManager ist ein Servicefinder.

Im Allgemeinen ist die Verwendung eines Service Locators für den Zugriff auf Abhängigkeiten in einem Objekt ziemlich schlecht, auschecken dieser Artikel.

Die explizite Definition Ihrer Abhängigkeiten durch einen Konstruktor ist ein viel besserer Ansatz.Es hilft bei Komponententests und Laufzeitproblemen, bei denen Dienste nicht definiert sind.

Wenn Sie den Objektmanager in eine Klasse einfügen, wird im Grunde eine Registrierung in Ihre Klasse eingefügt, die Zugriff auf alle Ihre Anwendungsdienste hat, was offensichtlich nicht richtig ist.

Ich benutze ZF2 ein gutes Stück und definieren im Allgemeinen kleine Factory-Klassen für Dienste, Controller und alle Klassen, die Abhängigkeiten erfordern.Diese Factory-Klassen haben Zugriff auf den Service Locator und greifen auf alle Services zu, von denen das Objekt abhängt, und injizieren sie über den Konstruktor.Die Verwendung eines Service-Locators in einer Factory-Klasse ist in Ordnung, da es sich meistens um Wegwerfcode handelt, so etwas wie dieser beispielsweise.

Diese Fabriken sind immer noch leicht zu Test.

IMO, Verwenden Sie Konstruktorinjektion, wo immer dies möglich ist.Auch hier weiß ich nicht viel über die Implementierung von Magento und wenn es das Konzept von Fabriken hat, sieht es auf den ersten Blick so aus, als würde es sie unterstützen, aber das explizite Definieren Ihrer Klassen und das Verwenden eines Service Locators zum Erstellen in Fabrikklassen ist ein viel sauberer Ansatz.

Dies ist von jemandem, der nur begrenzt mit den oben genannten Mustern in Berührung kommt, daher würde ich auch gerne die Gedanken / Erfahrungen anderer zu diesem Thema hören!

Mehr lesen

Eine andere Möglichkeit, Helfer (in Vorlagen) zu verwenden, ist:

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

Ich hoffe, es ist nützlich, wenn Sie es noch nicht wussten.

Obwohl es eine alte Frage ist, bin ich mir nicht sicher, ob Marius habe seine Antwort bekommen.Ich glaube Marius kann es besser beantworten.Ich möchte es kurz beantworten.Warum schlägt Magento 2 vor, DI anstelle von Helper zu verwenden?

  • Isolation im Komponententest möglich / einfach machen
  • Abhängigkeiten einer Klasse explizit definieren
  • Förderung guter Gestaltung (Single Responsibility Principle (SRP)) für Beispiel)
  • Die Verwendung von DI in Ihrem Modul verringert das Risiko von Inkompatibilitätsfehlern, wenn Magento ändert die zugrunde liegende Implementierung dieser Schnittstellen.Dies ist ein wichtiges Konzept, das für Erweiterungsentwickler zu verstehen ist.

Warum verwendet M2 Core in einigen Fällen möglicherweise keine DI?

  • Abnehmende Anzahl von Klassen
  • Keine unnötigen Schnittstellen schaffen
  • Kein Risiko von Inkompatibilitätsfehlern

Obwohl das Kernkatalogmodul als Helfer verwendet wurde, hat es DI ausgiebig verwendet.Bei meinen Recherchen habe ich festgestellt, dass Magento 2 nur wenige Funktionen in Kernkatalog-Hilfsdateien verwendet, die nicht für Serviceverträge geeignet sind.

Wenn Sie explizit eine von Magento definierte Klasse verwenden müssen (z. B. \Magento\Catalog\Model\Product ), machen Sie die implizite Abhängigkeit explizit, indem Sie von der konkreten Implementierung anstelle der Servicevertragsschnittstelle abhängen.

Zweifellos sollte der Erweiterungsentwickler DI anstelle von Magento1 wie Helper verwenden.Bei der Implementierung nach den Richtlinien von Magento 2 halten sich die Auswirkungen in Grenzen.Wenn Empfehlungen gebrochen werden, treten Probleme auf.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top