Magento2: qual é a diferença básica entre plugin e preferência?

47

Eu usei o plugin e a preferência no tutorial magento2 e ambos estão funcionando bem, mas qual é a diferença básica entre eles.

Código para o plugin:

1.1) Adicione uma declaração de plug-in no di.xml:

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

1.2) Crie uma classe de plug-in:

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

Código de preferência:

2.1) Crie uma declaração de preferência:

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

2.2) Crie uma nova classe de produto:

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

Respostas:

59

Uma preferência é equivalente à reescrita de classe do Magento 1. É equivalente a dizer: "Sempre que o código solicitar ClassA, forneça-o MyClassB". MyClassBdeverá ser uma implementação completa de ClassA, além de qualquer comportamento que você adicione ou modifique no topo.

Como no Magento 1, apenas uma preferência (reescrita) pode estar ativa para uma classe de uma vez, a menos que você as encadeie manualmente (de forma que MyClassBse estenda OtherClassBe OtherClassBse estenda ClassA).

Um plug-in permite executar o código antes, ao redor ou depois dos métodos da classe na qual você está se conectando. Sua classe de plug-in não substitui a classe de destino e não é uma instância dela. Você apenas tem métodos before{method}, around{method}, after{method}que são executados no momento apropriado em relação a {método} na classe alvo.

Como os plug-ins não substituem a classe de destino, qualquer número de plug-ins pode estar ativo em uma classe simultaneamente. O Magento apenas os executa um após o outro com base no parâmetro sortOrder no seu XML.

Por isso, os plugins são muito mais flexíveis que as preferências. Você deve usar plug-ins sempre que possível e evitar preferências para reescrever classes, a menos que seja absolutamente necessário.

Você pode ler mais sobre como os plug-ins funcionam e como usá-los na documentação oficial .

Ryan Hoerr
fonte
Preferência não é equivalente à reescrita de classe. É uma maneira de fornecer implementação padrão para interfaces.
Kandy
1
@KAndy Esse pode ser o objetivo básico, mas um efeito colateral disso é que eles também funcionam para substituir a classe. Semanticamente eles são os mesmos. A reescrita da aula por meio de preferências é o que Yogesh estava perguntando e também o que os exercícios de Fundamentos nos quais ele estava trabalhando instrui você a fazer.
Ryan Hoerr
12

Em palavras simples

A preferência é usada para substituir a classe

O plug-in é usado para adicionar funcionalidades antes, depois e em torno dos métodos.

Para Como seu exemplo:

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

Sempre que o código solicita o ListProduct, a preferência diz que

Ei, use em Vendor\MyModule\Block\Product\ListProduct vez 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>

Sempre que o código pede getPrice (), o plug-in dizia que

Ei, use meu getPrice() método antes, depois e ao redor do seu getPrice() método

Prince Patel
fonte
1

Em resumo :

A preferência é usada para especificar a implementação padrão de uma interface.

Plugin (Interceptor) é usado para estender o comportamento de um método público de outra classe.

Em detalhe :

Preferência: se houver mais de uma classe que implementa uma interface, é importante especificar a padrão de todas as classes implementadas. Isso é feito através do nó de preferência no arquivo de injeção de dependência (di.xml).

Exemplo:

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

Como está mapeado app/etc/di.xml, o gerenciador de objetos injeta a Magento\Core\Model\Urlclasse de implementação sempre que houver uma solicitação Magento\Core\Model\UrlInterfaceno escopo global.

Plugin (Interceptor):

Digamos, uma classe Atem um método methodAque precisa de uma funcionalidade estendida. Em seguida, isso é alcançado por meio de plug-ins criando classe APluginsem modificar a classe original A. A classe APluginpossui métodos que são executados antes, depois ou ao redor do método necessário.

Exemplo:

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

Esse mapeamento está no aplicativo / etc / di.xml. Um / poucos dos Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStockmétodos da classe são executados antes / depois / ao redor dos Magento\Catalog\Model\Plugin\ShowOutOfStockConfigmétodos da classe .

nikin
fonte