Magento2: ¿cuál es la diferencia básica entre plugin y preferencia?

47

Utilicé el complemento y la preferencia en el tutorial de magento2 y ambos funcionan bien, pero ¿cuál es la diferencia básica entre ellos?

Código para el complemento:

1.1) Agregue una declaración de complemento en di.xml:

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

1.2) Crear una clase de complemento:

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

Código de preferencia:

2.1) Crear una declaración de preferencia:

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

2.2) Crear una nueva clase de producto:

<?php
namespace Training\Test\Model;
class Testproduct extends \Magento\Catalog\Model\Product
{
public function getPrice() {
return 3;
}
}
Yogesh Karodiya
fuente

Respuestas:

59

Una preferencia es equivalente a la reescritura de clase de Magento 1. Es equivalente a decir: "Siempre que el código lo solicite ClassA, en MyClassBlugar de eso, déselo". MyClassBse espera que sea una implementación completa ClassA, además de cualquier comportamiento que agregue o modifique en la parte superior.

Al igual que en Magento 1, solo una preferencia (reescribir) puede estar activa para una clase a la vez, a menos que las encadene manualmente (de modo que se MyClassBextienda OtherClassBy se OtherClassBextienda ClassA).

Un complemento le permite ejecutar código antes, alrededor o después de los métodos de la clase a la que se está conectando. Su clase de complemento no reemplaza la clase de destino, y no es una instancia de ella. Sólo tienes métodos before{method}, around{method}, after{method}, que se ejecutan en el momento adecuado con respecto a {} método en la clase de destino.

Dado que los complementos no reemplazan la clase de destino, cualquier cantidad de complementos puede estar activa en una clase simultáneamente. Magento simplemente los ejecuta uno tras otro en función del parámetro sortOrder en su XML.

Por eso, los complementos son mucho más flexibles que las preferencias. Debe usar complementos siempre que sea posible y evitar las preferencias para reescribir clases a menos que sea absolutamente necesario.

Puede leer más sobre cómo funcionan los complementos y cómo usarlos en la documentación oficial .

Ryan Hoerr
fuente
La preferencia no es equivalente a la reescritura de clase. Es una forma de proporcionar una implementación predeterminada para las interfaces.
KAndy
1
@KAndy Ese puede ser el propósito básico previsto, pero un efecto secundario de eso es que también funcionan para anular la clase. Semánticamente son lo mismo. La reescritura de clases a través de preferencias es lo que Yogesh estaba preguntando, y también lo que el ejercicio de Fundamentos en el que estaba trabajando le indica que haga.
Ryan Hoerr
12

En palabras simples

La preferencia se usa para anular la clase

El complemento se utiliza para agregar funcionalidad antes, después y alrededor de los métodos.

Por como su ejemplo:

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

Cada vez que el código solicita ListProduct, la preferencia dice que

Hey, usa en Vendor\MyModule\Block\Product\ListProduct lugar de 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>

Cada vez que el código solicita getPrice (), el complemento dice que

Hey, usa mi getPrice() método antes, después y alrededor de tu getPrice() método

Príncipe Patel
fuente
1

En breve :

La preferencia se utiliza para especificar la implementación predeterminada de una interfaz.

Plugin (Interceptor) se usa para extender el comportamiento de un método público de otra clase.

En detalle :

Preferencia: si hay más de una clase que implementa una interfaz, entonces es importante especificar la predeterminada de todas las clases implementadas. Esto se realiza a través del nodo de preferencia en el archivo de inyección de dependencia (di.xml).

Ejemplo:

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

Esta asignación está activada app/etc/di.xml, por lo que el administrador de objetos inyecta la Magento\Core\Model\Urlclase de implementación siempre que haya una solicitud para el Magento\Core\Model\UrlInterfacealcance global.

Plugin (interceptor):

Digamos, una clase Atiene un método methodAque necesita una funcionalidad extendida. Luego, esto se logra a través de complementos creando una clase APluginsin modificar la clase original A. La clase APlugintiene métodos que se ejecutan antes, después o alrededor del método requerido.

Ejemplo:

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

Esta asignación se encuentra en la aplicación / etc / di.xml. Uno / pocos de los Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStockmétodos de clase se ejecutan antes / después / alrededor de los Magento\Catalog\Model\Plugin\ShowOutOfStockConfigmétodos de clase .

nikin
fuente