93

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\...


26

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 ...


11

No, plugins on virtual types do not work. Proof of concept code: <?php namespace Training\Example\Model class Type { public function bar() { return __CLASS__; } } Plugin using <type>: <?php namespace Training\Example\Model; class TypePlugin { public function afterBar(Type $subject) { return __CLASS__; ...


10

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....


9

The name of virtual type is just a globally unique string. There is no difference in behavior for differently named virtual types. We just don't have strong naming convention for virtual types. I personally prefer second approach because it makes it obvious that this is virtual type, not a real class.


6

Let's say you want to change the links one. You have to create your own module that depends on the Magento_Downloadable module and add this in the di.xml of your module. <type name="Magento\Downloadable\Ui\DataProvider\Product\Form\Modifier\Composite"> <arguments> <argument name="modifiers" xsi:type="array"> <...


5

I needed to strong type the argument. class Test extends \Magento\Framework\App\Action\Action { protected $test; public function __construct( Context $context, \Company\Extension\Model\Product\Attribute\Source\Test $test //changes on this line ) { $this->test = $test; parent::__construct($context); } ...


5

What you're trying won't work because php must be able to find the class that you are giving in a constructor argument's type hint. This is part of the language and can't be overriden. Php is unaware of di.xml settings. The object that Object Manager passes to a constructor must implement or inherit from the given type hint. In the case of virtual types, ...


4

The configurations declared via virtualType are not sub-classes of base class. Virtual types with class-similar names add some confusion in this problem. You need to perceive "virtual types" as configured instances of base class. Example: di.xml <virtualType name="LetterA" type="Magento\Framework\Alphabet\CharacterInterface"&...


4

Plugins will work for virtual type but only if you specify it for parent classes or interfaces, but you cannot specify plugin specific for concrete virtual type


3

This isn't possible because the core routers build the action list using \Magento\Framework\Module\Dir\Reader::getActionFiles source, which loads the available actions by reading files contained in each module's Controller directory. Below is the function as it currently exists in 2.3-develop: public function getActionFiles() { $actions = []; ...


3

\Magento\Checkout\Controller\Cart::getBackUrl() is protected method and that's why it cannot be pluginized. Plugins can be created only for public non-static methods. In the provided example with virtual type, virtual URL should be passed as an argument to action controller, not vice versa. Something like this: <virtualType name="myCustomUrl" type="...


2

the di.xml files are merged, so it if you copy the markup you mentioned in your module and remove a line, when the merge is done, the original file will be merge too and you will still get that line. An option would be to create your own virtual type that does not contain the category item and make all the models that used the original catalogFilerList ...


2

Most probably you can't directly extend the virtual class in php file. But you can do with di.xml itself. Take this example, this may help you. <virtualType name="SectionInvalidationConfigReader" type="Magento\Framework\Config\Reader\Filesystem"> <arguments> <argument name="idAttributes" xsi:type="array"> <item ...


2

I think it is because the class you are trying to override via preferences is actually being used by the system via virtualtype. vendor/magento/module-paypal/etc/di.xml <virtualType name="Magento\Paypal\Model\Payflow\Service\Response\Validator\ResponseValidatorInController" type="Magento\Paypal\Model\Payflow\Service\Response\Validator\ResponseValidator"&...


2

<preferance> - is directive for mapping type to interface <type> - is directive for configure concrete type <virtualType> - is directive for create alias for type Example: class A { function __construct( AInt $a, BInt $b ) } You can not create such class, because it contains link to Interfaces So you can map interfaces to ...


2

So I did a little more digging. The result is that the virtual types work nicely for cron configuration. The problem for me what that I was configuring the virtual types wrong. Here is my cron configuration <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:...


2

Let's break down the dependency chain going from controller. First argument is \Magento\Framework\App\Action\Context $context which is core object and will work as expected provided nothing has been altered. The next argument that the DI will want to inject is Modelclass $Modelclass, which resolves to Test\Testmod\Model\Modelclass as defined in use ...


1

Found it. I forgot this part <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">


1

95% sure that it works. If the Source Model is instantiated by the ObjectManager (I really think, or at least hope so, the Object Manager just creates a new Object of [Namespace]\[Module]\Model\Source\Options with the parameters defined for SomeTypeNameHere


Only top voted, non community-wiki answers of a minimum length are eligible