
Magento 2 introduces powerful features to simplify development and customization, but some concepts, like the difference between Type and Virtual Type in Magento 2, can be challenging to grasp. Understanding this distinction is essential for optimizing dependency injection and module development in Magento 2.
This guide will break down the differences with clear examples, helping you understand when and why to use Type or Virtual Type. By the end, you’ll have a solid grasp of their roles and how they contribute to flexible and efficient code in Magento 2.
Let’s dive in and explore these key components step by step.
What is Type in Magento 2?
In Magento 2, a Type represents a class that is directly defined and configured in the di.xml
file for dependency injection (DI). It is a blueprint for creating instances of a specific class within the Magento framework. When a Type is defined, Magento automatically instantiates the class and resolves its dependencies.
Key Characteristics of Type:
- Direct Class Reference: A Type is tied directly to a class name in your codebase.
- Singleton Behavior: By default, Magento instantiates a Type as a singleton, ensuring the same instance is reused wherever required.
- Defined in di.xml: The
di.xml
file is used to specify the Type and its dependencies, making it a core part of Magento’s DI system.
What is Virtual Type in Magento 2?
A Virtual Type in Magento 2 is not tied to a specific class. Instead, it creates a new instance configuration based on an existing class (Type) but with customized dependencies. Virtual Types allow developers to reuse a base class with different arguments without modifying the original class or creating a new one.
Key Characteristics of Virtual Type:
- No Physical Class: Virtual Types don’t have a corresponding PHP class file; they rely on an existing class as a base.
- Customizable Dependencies: You can alter the arguments of a class without affecting the original Type.
- Defined in di.xml: Virtual Types are also defined in
di.xml
, with thevirtualType
tag.
Practical Example of Difference Between Type and Virtual Type:
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Codedecorator_Learning',
__DIR__
);
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Codedecorator_Learning" setup_version="1.0.0" />
</config>
<?php
namespace Codedecorator\Learning\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Codedecorator\Learning\Model\ClassDefault;
class Index extends Action
{
protected $classDefault;
public function __construct(
Context $context,
ClassDefault $classDefault
)
{
$this->classDefault = $classDefault;
parent::__construct($context);
}
public function execute()
{
echo "Index ClassA Namespace : ".$this->classDefault->namespace;
}
}
<?php
namespace Codedecorator\Learning\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Codedecorator\Learning\Model\ClassDefault;
class Submit extends Action
{
protected $classDefault;
public function __construct(
Context $context,
ClassDefault $classDefault
)
{
$this->classDefault = $classDefault;
parent::__construct($context);
}
public function execute()
{
echo "Submit ClassA Namespace : ".$this->classDefault->namespace;
}
}
<?php
namespace Codedecorator\Learning\Model;
class ClassDefault
{
public $namespace;
public function __construct($namespace = 'default')
{
$this->namespace = $namespace;
}
}
So, we have added two controllers and one model file. Please check the Model file carefully. We have one class property and its default value is “default”.
We are trying to use this ClassDefault.php file in one of our controllers and trying to print the property of model class.
If try to call the controller by url then we will receive the “default” for both controllers. For example:


As you see in above screenshot property name is coming default in both the controller so lets try to change the ClassDefault property default value without modifying the class directly and do so we can just need to add di.xml
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!-- Changing value for both Controllers -->
<type name="Codedecorator\Learning\Model\ClassDefault">
<arguments>
<argument name="namespace" xsi:type="string">test</argument>
</arguments>
</type>
</config>
As you noticed that we have used the type node and we have changed the namspace property from the default to test. Let’s flush cache as we have changed in the XML file and check the result.


Yes, result changed and it is showing test instead of the default for both the controller.
I guess now you understand concept of type that it will change the property value for all the controller which is using the DefaultClass.php
If we want to change the property value for the Index.php controller and not for the Submit.php controller so here virtualType node comes in picture. It will allow us to create subclass and use that class wherever required. If you still have confusion check the updated di.xml and see the result.
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<virtualType name="ClassDefaultVirtual" type="Codedecorator\Learning\Model\ClassDefault">
<arguments>
<argument name="namespace" xsi:type="string">test</argument>
</arguments>
</virtualType>
<type name="Codedecorator\Learning\Controller\Index\Index">
<arguments>
<argument name="classDefault" xsi:type="object">ClassDefaultVirtual</argument>
</arguments>
</type>
</config>
You should flush the cache after making anything changes in XML files. Here is the result:


I hope this example helps you understand the difference between Type and Virtual Type in Magento 2. Feel free to leave a comment if you have any questions or need further clarification.
Share Post
Comments (2)
zargamsays:
June 22, 2023 at 7:59 amThank you so much!
Zargamsays:
May 9, 2024 at 7:46 amThanks!