Magento 2 Argument Types

Neste post, daremos continuidade aos estudos de Dependency Injection e começaremos a falar sobre Magento 2 Argument Types

No último post, começamos a falar sobre Depedency Injection no Magento 2 e como usá-lo para trabalhar com interfaces. Para isso, começamos a criar um módulo para trabalhar com Interfaces e daremos continuidade nele.

Desta vez, nós temos a seguinte estrutura de classe:

Nós criamos uma nova model:

<?php

namespace ForMage\Learning\Model\Product;

use ForMage\Learning\Api\ColorInterface;
use ForMage\Learning\Api\SizeInterface;

class Shoe
{
    protected $size;
    protected $color;

    public function __construct(ColorInterface $color, SizeInterface $size)
    {
        $this->color = $color;
        $this->size = $size;
    }

    public function getShoe()
    {
        return "My Shoe is {$this->size->getSize()} and {$this->color->getColor()}";
    }
}

Na model Shoe, temos a instância das duas interfaces no seu __construct() e um método que chama o Size e o Color das nossas interfaces.

Após isso, alteramos o nosso controller:

<?php

namespace ForMage\Learning\Controller\Page;

use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use ForMage\Learning\Api\SizeInterface;
use ForMage\Learning\Api\ColorInterface;
use ForMage\Learning\Model\Product\Shoe;

class Index extends \Magento\Framework\App\Action\Action
{
    protected $size;
    protected $color;
    protected $product;

    public function __construct(
        Context $context,
        SizeInterface $size,
        ColorInterface $color,
        Shoe $product
    ) {
        parent::__construct($context);
        $this->size = $size;
        $this->color = $color;
        $this->product = $product;
    }

    public function execute()
    {
        echo $this->product->getShoe();
    }
}

Qual a diferença que temos agora? Bom, fizemos um USE da nossa model Shoe e no método execute() imprimimos o resultado do método getShoe() da nossa Model com o seguinte resultado:

My Shoe is Small and White

Ok. Até aí nada demais. Mas e aí?

A questão é que para a classe concreta Shoe precisamos de uma lógica diferente. Todas as vezes que executamos os métodos $this->size->getSize() e $this->color->getColor() de suas respectivas interfaces, eles retornam a lógica de negócio que temos em ForMage\Learning\Model\ColorWhite e ForMage\Learning\Model\SizeSmall devido a configuração que já fizemos anteriormente em nosso di.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="ForMage\Learning\Api\SizeInterface"
                type="ForMage\Learning\Model\SizeSmall" />

    <preference for="ForMage\Learning\Api\ColorInterface"
                type="ForMage\Learning\Model\ColorWhite" />
    
</config>

Então, como faremos essa modificação?

É exatamente aí que entram o Argument Types

Magento 2 Argument Types

Os Argument Types são uma das grandes implementações adicionadas no Magento 2. Com eles, nós conseguimos alterar os parâmetros do __construct() de uma classe, sem afetar nenhum outro __construct() de qualquer outra classe.

Configurando os Argument Types do Construtor

<type name="ForMage\Learning\Model\Product\Shoe">
    <arguments>
        <argument name="color" xsi:type="object">ForMage\Learning\Model\ColorBlack</argument>
        <argument name="size" xsi:type="object">ForMage\Learning\Model\SizeGreat</argument>
    </arguments>
</type>

Declaramos a tag type:

<type name: A classe alvo. A classe que queremos alterar os parâmetros do seu construtor

<argument name: O parâmetro que desejamos interceptar e alterar.

xsi:type=”object”: Qual será o tipo de dado passado para o argumento. Neste caso, será o tipo object (objeto).

Ficando o nosso di.xml assim:

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="ForMage\Learning\Api\SizeInterface"
                type="ForMage\Learning\Model\SizeSmall" />

    <preference for="ForMage\Learning\Api\ColorInterface"
                type="ForMage\Learning\Model\ColorWhite" />

    <type name="ForMage\Learning\Model\Product\Shoe">
        <arguments>
            <argument name="color" xsi:type="object">ForMage\Learning\Model\ColorBlack</argument>
            <argument name="size" xsi:type="object">ForMage\Learning\Model\SizeGreat</argument>
        </arguments>
    </type>
</config>

Entendendo o seu funcionamento:

Onde temos <argument name="color" xsi:type="object">ForMage\Learning\Model\ColorBlack</argument> estamos falando para o Magento 2 que o parâmetro color receberá o objeto ColorBlack e que <argument name="size" xsi:type="object">ForMage\Learning\Model\SizeGreat</argument> o parâmetro size receberá o objecto SizeGreat.

Ao executarmos a nossa rota novamente, temos o seguinte resultado:

My Shoe is Great and Black.

Com isso, conseguimos alterar o comportamento do construtor de uma classe específica, apenas usando Argument Types no Magento 2.

Dúvidas? Posta aí!

Um abraço!

 

 

 

 

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *