Virtual Type in magento 2

Virtual Type in magento 2

In This blog , we will learn about Virtual Type in magento 2.

What is Virtual Type?

When you want to create a virtual class and add it into any class as dependencies without affecting original class then you can use this functionality.

For example , You have classA and you want to change it’s argument for some particular module or class but want to keep remain as it is for any other module or class, then you have 2 choices either create another physical class and rewrite all code of Class A , else you can use virtual type functionality.

Let’s understand in detail how it works with practical example

First we will create a module with name VirtualTypeExample as below, If you don’t know how to create module in magento 2 you can either visit our previous blog or watch our video

app\code\Mageacademy\VirtualTypeExample

Now you can create a Console command and add code below

<?php
namespace Mageacademy\VirtualTypeExample\Console;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class FirstCommand extends Command
{
    const NAME = 'name';

    protected $helperClassA;

    public function __construct(
        \Mageacademy\VirtualTypeExample\Helper\HelperClassA $helperClassA,
        string $name = null)
    {
        $this->helperClassA = $helperClassA;
        parent::__construct($name);
    }
    /**
     * @inheritDoc
     */
    protected function configure()
    {
        $this->setName('mageacademy:virtualtype:showresult');
        $this->setDescription('Virtual Type');
        parent::configure();
    }
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $c = $this->helperClassA->getResult();
        $output->writeln($c);
    }
}

Now you can create Helper class A as below

<?php

namespace Mageacademy\VirtualTypeExample\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;

class HelperClassA extends AbstractHelper
{
    protected $a;

    public function __construct(Context $context,
        $a = 25
    )
    {
        $this->a = $a;
        parent::__construct($context);
    }


    public function getResult()
    {
        return $this->a;
    }

}

Now if you run enable module and run below command

mageacademy:virtualtype:showresult

then you will see below result

25

Now if you want to change argument of a with 20 , but only for particular class for example SecondCommand as below

<?php
namespace Mageacademy\VirtualTypeExample\Console;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class SecondCommand extends Command
{
    const NAME = 'name';

    protected $helperClassA;

    public function __construct(
        \Mageacademy\VirtualTypeExample\Helper\HelperClassA $helperClassA,
        string $name = null)
    {
        $this->helperClassA = $helperClassA;
        parent::__construct($name);
    }
    /**
     * @inheritDoc
     */
    protected function configure()
    {
        $this->setName('mageacademy:virtualtype:showresult2');
        $this->setDescription('Virtual Type 2');
        parent::configure();
    }
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $c = $this->helperClassA->getResult();
        $output->writeln($c);
    }
}

Here the command is mageacademy:virtualtype:showresult2 so if you will run this command for now then you will receive same 25 as result , but you want 20 instead of 25 if you will run mageacademy:virtualtype:showresult2 command and 25 if you will run mageacademy:virtualtype:showresult command , then how you can do it without creating a physical class , so to make this done we need to use virtualType as below

in di.xml you need to add below code

<virtualType name="HelperClassB" type="Mageacademy\VirtualTypeExample\Helper\HelperClassA">
    <arguments>
        <argument name="a" xsi:type="string">20</argument>
    </arguments>
</virtualType>

Above xml code will create a virtual Class HelperClassB which will be replica of HelperClassA, and in that HelperclassB I am changing argument of a to 20. but still it will not work as in SecondCommand class we have injected HelperClassA. So we need to use argument replacement here using <type> as below

type name="Mageacademy\VirtualTypeExample\Console\FirstCommand">
        <arguments>
            <argument name="helperClassA" xsi:type="object">HelperClassB</argument>
        </arguments>
    </type>

So here you can see that you are replace argument in SecondCommand class for helperclassA.

Now clear the cache and run di compile , and then run below command

mageacademy:virtualtype:showresult2

Result will be 20

and if you will run mageacademy:virtualtype:showresult then result will be 25

So by this way if you want to change argument of any class without affecting original class then you can use virtualType and make your work done

Hope you like my this blog and way of explaination.

Leave a Reply
Your email address will not be published. *