문제

In the di.xml that comes with Magento2 there is a node type and a node virtualType. My questions is what is this virtualType and in what case should it be used instead of type?

In some places it looks like a symbolic link or rewrite:

<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">

Where one full path gets changed into another but in other places it appears to be used as a way to define a shorter alias.

<virtualType name="lessFileSourceBase" type="Magento\Framework\View\File\Collector\Base">
도움이 되었습니까?

해결책

Virtual types are a way to inject different dependencies into existing classes without affecting other classes.

For example, the Magento\Framework\Session\Storage class takes a $namespace argument in its constructor, which defaults to the value 'default', and you could use the type definition to change the namespace to 'core'.

<type name="Magento\Framework\Session\Storage">
    <arguments>
        <argument name="namespace" xsi:type="string">core</argument>
    </arguments>
</type>

The above config would make it so that all instances of Magento\Framework\Session\Storage have a namespace of 'core'. Using a virtual type allows for the equivalent of a sub-class to be created, where only the sub-class has the altered argument values.

In the codebase we see the following two configurations:

<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">
    <arguments>
        <argument name="namespace" xsi:type="string">core</argument>
    </arguments>
</virtualType>

<type name="Magento\Framework\Session\Generic">
    <arguments>
        <argument name="storage" xsi:type="object">Magento\Core\Model\Session\Storage</argument>
    </arguments>
</type>

The first snippet creates a virtual type for Magento\Core\Model\Session\Storage which alters the namespace, and the second inject the virtual type into Magento\Framework\Session\Generic. This allows Magento\Framework\Session\Generic to be customized without affecting other classes that also declare a dependency on Magento\Framework\Session\Storage

다른 팁

Another way to understand virtual types -

Let's say that you have a class \Class1, which has the following constructor -

public function __construct(\Class2 $argOfClass1){...}

And \Class2 has the following constructor -

public function __construct(\Class3 $argOfClass2){...}

Now, you want to change the type of $argOfClass2 from \Class3 to \Class4, but only when \Class2 is used as $argOfClass1.

The "old" way to do that would be to add the following in di.xml -

<type name="Class1">
    <arguments>
         <argument name="argOfClass1" xsi:type="object">Class5</argument>
    </arguments>
</type>

where \Class5 is the following:

class \Class5 extends \Class2{
    public function __construct(\Class4 $argOfClass2){...}
}

Instead of using this way, you can use the virtual types to accomplish the same, by adding the following to di.xml:

<virtualType name="Class5" type="Class2">
    <arguments>
        <argument name="argOfClass2" xsi:type="string">Class4</argument>
    </arguments>
</virtualType>

<type name="Class1">
    <arguments>
         <argument name="argOfClass1" xsi:type="object">Class5</argument>
    </arguments>
</type>

As you can see, using the virtual type saved you the work of creation of Class5.

For further reference I suggest to read Alan Storm's article regarding virtual types in Magento2 - http://alanstorm.com/magento_2_object_manager_virtual_types/

In the same di.xml file I found that lessFileSourceBase is passed as an argument for lessFileSourceBaseFiltered that is passed as an argument for lessFileSourceBaseSorted that is passed as an argument for type Magento\Framework\Less\File\Collector\Aggregated.

I found no other occurrence of lessFileSourceBase (or lessFileSource ) in an other file except di.xml from the core module. Only in some cache files but those are not important.

I guess if you are not going to use the virtual type in a PHP class, but only in the di xml files then you are not required to make it look like a class name and you can use an alias.

But this is just pure speculation.
It will be "fun" to try to create a class and inject in its constructor an instance of lessFileSourceBase to see how it behaves.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 magento.stackexchange
scroll top