Magento2: в чем принципиальная разница между плагином и предпочтениями?

47

Я использовал оба плагина и предпочтения в учебнике magento2, и оба работают нормально, но в чем их основное отличие.

Код для плагина:

1.1) Добавьте объявление плагина в di.xml:

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

1.2) Создайте класс плагина:

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

Код для предпочтения:

2.1) Создайте объявление предпочтений:

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

2.2) Создайте новый класс Product:

<?php
namespace Training\Test\Model;
class Testproduct extends \Magento\Catalog\Model\Product
{
public function getPrice() {
return 3;
}
}
Йогеш Кародия
источник

Ответы:

59

Предпочтение эквивалентно переписыванию классов из Magento 1. Это равносильно тому, чтобы сказать: «Всякий раз, когда код просит ClassA, MyClassBвместо этого дайте им ». MyClassBожидается полная реализация ClassA, плюс любое поведение, которое вы добавляете или изменяете сверху.

Как и в Magento 1, только одно предпочтение (перезапись) может быть активным для класса за один раз, если вы не объедините их вручную (например, MyClassBрасширяет OtherClassBи OtherClassBрасширяет ClassA).

Плагин позволяет вам выполнять код до, вокруг или после методов из класса, к которому вы подключаетесь. Ваш класс плагина не заменяет целевой класс и не является его экземпляром. Вы просто методы before{method}, around{method}, after{method}которые получают исполненные в соответствующее время в отношении {метода} на целевом классе.

Поскольку плагины не заменяют целевой класс, любое количество плагинов может быть активным в классе одновременно. Magento просто выполняет их один за другим на основе параметра sortOrder в вашем XML.

Из-за этого плагины гораздо более гибкие, чем настройки. Вы должны использовать плагины всякий раз, когда это возможно, и избегать предпочтений для переписывания классов, если в этом нет крайней необходимости.

Вы можете узнать больше о том, как плагины работают и как их использовать, в официальной документации .

Райан Херр
источник
Предпочтение не эквивалентно переписыванию классов. Это способ обеспечить реализацию по умолчанию для интерфейсов.
Канди
1
@Kandy Это может быть основной целью, но побочным эффектом является то, что они также работают для переопределения класса. Семантически они одинаковы. Йогеш спрашивал о переписывании классов с помощью предпочтений, а также о том, что упражнение по Основам, над которым он работал, учит вас делать.
Райан Херр
12

Простыми словами

Предпочтение используется для переопределения класса

Плагин используется для добавления функциональности до, после и вокруг методов.

Для вашего примера:

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

Всякий раз, когда код запрашивает ListProduct, предпочтение говорит, что

Эй, используйте Vendor\MyModule\Block\Product\ListProduct вместо 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>

Всякий раз, когда код запрашивает getPrice (), плагин говорит, что

Эй, используйте мой getPrice() метод до, после и вокруг вашего getPrice() метода

Принц Патель
источник
1

Вкратце :

Предпочтение используется, чтобы указать реализацию интерфейса по умолчанию.

Плагин (Interceptor) используется для расширения поведения открытого метода другого класса.

В деталях :

Предпочтение: если существует более одного класса, реализующего интерфейс, важно указать один из всех реализованных классов по умолчанию. Это делается через узел предпочтений в файле внедрения зависимостей (di.xml).

Пример :

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

Это отображение включено app/etc/di.xml, поэтому диспетчер объектов внедряет Magento\Core\Model\Urlкласс реализации везде, где есть запрос для Magento\Core\Model\UrlInterfaceв глобальной области.

Плагин (Перехватчик):

Скажем, у класса Aесть метод, methodAкоторый требует расширенной функциональности Затем это достигается с помощью плагинов путем создания класса APluginбез изменения исходного класса A. У класса APluginесть методы, которые выполняются до, после или вокруг требуемого метода.

Пример :

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

Это сопоставление находится в приложении / etc / di.xml. Один / несколько методов класса Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStockвыполняются до / после / вокруг Magento\Catalog\Model\Plugin\ShowOutOfStockConfigметодов класса .

nikin
источник