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!