Virtual type is one of the most common design patterns in magento2. Basically, it allows us to modify existing classes without affecting other classes and inject them where we need them
Type allows us to modify dependencies injected to a constructor.
Consider following chunk of code:
1 2 3 4 5 6 7 8 9 |
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory"> <arguments> <argument name="collections" xsi:type="array"> <item name="bluethink_post_listing_data_source" xsi:type="string">Bluethink\Crud\Model\ResourceModel\Post\Grid\Collection</it em> </argument> </arguments> </type> |
We basically pass an object of our Bluethink\Crud\Model\ResourceModel\Post\Grid\Collection class to the Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory constructor of the bluethink_post_listing_data_source variable.
But type isn’t just about objects. It can be any value (e.g. array) that can be passed to the constructor.
Consider following chunk of code:
1 2 |
<virtualType name=" Grid " type="Magento\Catalog\Product\Model\Grid"> </virtualType> |
The above code is almost same as creating a PHP class Grid:
1 2 |
<?php class Grid extend \Magento\Catalog\Product\Model\Grid |
Here is another chunk of code:
1 2 3 4 5 6 7 8 |
<virtualType name="Bluethink\Crud\Model\ResourceModel\Post\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult"> <arguments> <argument name="mainTable" xsi:type="string">bluethink_helloworld_post</argument> <argument name="resourceModel" xsi:type="string"> Bluethink\Crud\Model\ResourceModel\Post</argument> </arguments> </virtualType> |
In the above example, We are modifying the constructor argument mainTable and resourceModel of class Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
Consider you want to make a coffee for a party and each guest is told to bring a cup of coffee.
First, use the Espresso class in your code, where you’ll throw the coffee cups’ contents.
1 2 3 4 5 6 7 8 9 |
<?php namespace Vendor\Module; class Espresso { public function __construct(array $cups = []) { var_dump($cups); } } |
Now, you would put all coffee flavors into the Cup class:
1 2 3 4 5 6 7 8 9 10 11 |
<?php namespace Vendor\Module; class Cup { private $flavors; public function __construct(array $ flavors = []) { $this-> flavors = $ flavors; } } |
Now collect the flavor cup and then move them into the Espresso. Let’s assume you first create 2 cups; one with Amaretto & chocolate and another with Hazelnut & Almond.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<virtualType name="FirstCup" type="Vendor\Module\Cup"> <arguments> <argument name="flavors" xsi:type="array"> <item name=" amaretto" xsi:type="string"> Amaretto </item> <item name="chocolate" xsi:type="string"> chocolate </item> </argument> </arguments> </virtualType> <virtualType name="SecondCup" type="Vendor\Module\Cup"> <arguments> <argument name="flavors" xsi:type="array"> <item name="hazelnut" xsi:type="string"> Hazelnut </item> <item name="almond" xsi:type="string"> Almond </item> </argument> </arguments> </virtualType> |
Next, we have our cups ready, let’s move them inside Espresso:
1 2 3 4 5 6 7 8 |
<type name="Vendor\Module\Espress"> <arguments> <argument name="cups" xsi:type="array"> <item name="firstCup" xsi:type="object">FirstCup</item> <item name="secondCup" xsi:type="object">SecondCup</item> </argument> </arguments> </type> |
Conclusion: Now the cups are now in the espresso, and you are ready to make coffee 😉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
array(2) { ["firstCup]=> object(Vendor\Module\Cup)#660 (1) { ["flavors":"Vendor\Module\Cup":private]=> array(2) { ["amaretto "]=> string(8) "Amaretto" [" chocolate "]=> string(9) "Chocolate " } } ["secondCup"]=> object(Vendor\Module\Cup)#661 (1) { ["flavors":"Vendor\Module\Cup":private]=> array(2) { ["hazelnut"]=> string(8) "Hazelnut " [" almond"]=> string(6) "Almond" } } } |
Vikas Mishra
2024-02-06