Magento2: jaka jest podstawowa różnica między wtyczką a preferencjami?

47

Użyłem zarówno wtyczki, jak i preferencji w tutorialu magento2 i oba działają dobrze, ale jaka jest podstawowa różnica między nimi.

Kod wtyczki:

1.1) Dodaj deklarację wtyczki do di.xml:

<type name="Magento\Catalog\Model\Product">
<plugin name="magento-catalog-product-plugin" type="Training\Test\Model\Product" sortOrder="10"/>
</type>

1.2) Utwórz klasę wtyczek:

<?php
namespace Training\Test\Model;
class Product {
public function afterGetPrice(\Magento\Catalog\Model\Product $product, $result) {
return 5;
}
}

Kod preferencji:

2.1) Utwórz deklarację preferencji:

<preference for="Magento\Catalog\Model\Product"
type="Training\Test\Model\Testproduct" />

2.2) Utwórz nową klasę produktu:

<?php
namespace Training\Test\Model;
class Testproduct extends \Magento\Catalog\Model\Product
{
public function getPrice() {
return 3;
}
}
Yogesh Karodiya
źródło

Odpowiedzi:

59

Preferencja jest równoważna przepisywaniu klas z Magento 1. Odpowiada powiedzeniu: „Ilekroć kod prosi o kod ClassA, daj je MyClassBzamiast tego”. MyClassBoczekuje się, że będzie to pełna implementacja ClassA, a także dowolne zachowanie dodane lub zmodyfikowane na górze.

Podobnie jak w Magento 1, tylko jedna preferencja (przepisywanie) może być aktywna dla klasy w tym samym czasie, chyba że połączymy je ręcznie (takie, które MyClassBrozszerza OtherClassBi OtherClassBrozszerza ClassA).

Wtyczka umożliwia wykonywanie kodu przed, w pobliżu lub po metodach z klasy, do której się zaczepiasz. Twoja klasa wtyczek nie zastępuje klasy docelowej i nie jest jej instancją. Trzeba tylko metody before{method}, around{method}, after{method}który zostanie wykonany w odpowiednim czasie w odniesieniu do metody {} w klasie docelowej.

Ponieważ wtyczki nie zastępują klasy docelowej, dowolna liczba wtyczek może być aktywna w klasie jednocześnie. Magento wykonuje je po kolei na podstawie parametru sortOrder w pliku XML.

Z tego powodu wtyczki są znacznie bardziej elastyczne niż preferencje. Powinieneś używać wtyczek, gdy tylko jest to możliwe, i unikać preferencji dotyczących przepisywania klas, chyba że jest to absolutnie konieczne.

Możesz przeczytać więcej o tym, jak działają wtyczki i jak ich używać w oficjalnej dokumentacji .

Ryan Hoerr
źródło
Preferencje nie są równoważne przepisywaniu klas. Jest to sposób na zapewnienie domyślnej implementacji interfejsów.
KAndy,
1
@KAndy Może to być podstawowy zamierzony cel, ale efektem ubocznym jest to, że działają również w przypadku przesłonięcia klasy. Semantycznie są takie same. Przepisywanie klas za pomocą preferencji jest tym, o co pytał Yogesh, a także o to, jakie ćwiczenie Podstawy, nad którym pracował, instruuje cię.
Ryan Hoerr
12

W prostych słowach

Preferencje są używane do nadpisywania klas

Wtyczka służy do dodawania funkcjonalności przed, po i wokół metod.

Jako Twój przykład:

<preference for="Magento\Catalog\Block\Product\ListProduct" type="Vendor\MyModule\Block\Product\ListProduct" /> 

Za każdym razem, gdy kod pyta o ListProduct, preferencja tak mówi

Hej, użyj Vendor\MyModule\Block\Product\ListProduct zamiast Magento\Catalog\Block\Product\ListProduct

<type name="Magento\Catalog\Model\Product">
<plugin name="magento-catalog-product-plugin" type="Training\Test\Model\Product" sortOrder="10"/>
</type>

Ilekroć kod pyta o getPrice (), wtyczka tak mówi

Hej, użyj mojej getPrice() metody przed, po i wokół twojej getPrice() metody

Książę Patel
źródło
1

W skrócie :

Preferencje służą do określenia domyślnej implementacji interfejsu.

Plugin (Interceptor) służy do przedłużenia działania metody publicznej innej klasy.

Szczegółowo :

Preferencje: Jeśli istnieje więcej niż jedna klasa, która implementuje interfejs, ważne jest, aby określić domyślną jedną ze wszystkich zaimplementowanych klas. Odbywa się to za pośrednictwem węzła preferencji w pliku wstrzykiwania zależności (di.xml).

Przykład:

<preference for="Magento\Catalog\Block\Product\ListProduct" type="Vendor\MyModule\Block\Product\ListProduct" /> 

Odwzorowanie jest włączone app/etc/di.xml, więc menedżer obiektów wstrzykuje Magento\Core\Model\Urlklasę implementacji wszędzie tam, gdzie jest żądanie Magento\Core\Model\UrlInterfacew zakresie globalnym.

Wtyczka (przechwytywacz):

Powiedzmy, klasa Ama metodę, methodAktóra wymaga rozszerzonej funkcjonalności. Następnie osiąga się to poprzez wtyczki, tworząc klasę APluginbez modyfikowania oryginalnej klasy A. Klasa APluginma metody działające przed, po lub wokół wymaganej metody.

Przykład:

<config>
    <type name="Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStock">
        <plugin name="showOutOfStockValueChanged" type="Magento\Catalog\Model\Plugin\ShowOutOfStockConfig"/>
    </type>
</config>

To mapowanie znajduje się w app / etc / di.xml. Jedna / Kilka Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStockmetod klasy jest wykonywana przed / po / wokół Magento\Catalog\Model\Plugin\ShowOutOfStockConfigmetod klasy .

nikin
źródło