В di.xml
комплекте с Magento2 есть узел type
и узел virtualType
. Мои вопросы: что это такое virtualType
и в каком случае его следует использовать вместо type
?
В некоторых местах это выглядит как символическая ссылка или переписать:
<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">
Там, где один полный путь изменяется на другой, но в других местах он используется для определения более короткого псевдонима.
<virtualType name="lessFileSourceBase" type="Magento\Framework\View\File\Collector\Base">
magento2
dependency-injection
virtualtype
Дэвид Мэннерс
источник
источник
Magento\Framework\ObjectManager\Config\Mapper\Dom::convert
. Там где-то естьswitch
утверждение.lessFileSourceBase
ограничен ли он xml или его можно использовать и снаружи. Думаю, мне лучше покопаться.Ответы:
Виртуальные типы - это способ внедрить различные зависимости в существующие классы, не затрагивая другие классы.
Например,
Magento\Framework\Session\Storage
класс принимает$namespace
аргумент в своем конструкторе, который по умолчанию имеет значение «default», и вы можете использоватьtype
определение, чтобы изменить пространство имен на «core».Приведенный выше конфиг сделает так, чтобы все экземпляры
Magento\Framework\Session\Storage
имели пространство имен «core». Использование виртуального типа позволяет создать эквивалент подкласса, где только подкласс имеет измененные значения аргумента.В кодовой базе мы видим следующие две конфигурации:
Первый фрагмент создает виртуальный тип, для
Magento\Core\Model\Session\Storage
которого изменяется пространство имен, а второй вводит виртуальный тип вMagento\Framework\Session\Generic
. Это позволяетMagento\Framework\Session\Generic
настраивать, не затрагивая другие классы, которые также объявляют зависимость отMagento\Framework\Session\Storage
источник
<type>
использует виртуальный класс, который на самом деле не существует. Таким образом, изменение аргумента вvirtualType
вступит в силу только тогда, когда будет инициализирован класс, использующий virtualType, какMagento\Framework\Session\Generic
в примереЕще один способ понять виртуальные типы -
Допустим, у вас есть класс
\Class1
, который имеет следующий конструктор -И
\Class2
имеет следующий конструктор -Теперь вы хотите изменить тип
$argOfClass2
с\Class3
на на\Class4
, но только когда\Class2
используется как$argOfClass1
.«Старый» способ сделать это будет добавить следующее в
di.xml
-где
\Class5
следующее:Вместо этого вы можете использовать виртуальные типы для достижения того же, добавив следующее в
di.xml
:Как видите, использование виртуального типа избавило вас от работы по созданию
Class5
.Для дальнейшего ознакомления предлагаю прочитать статью Алана Шторма о виртуальных типах в Magento2 - http://alanstorm.com/magento_2_object_manager_virtual_types/
источник
В том же
di.xml
файле я обнаружил, чтоlessFileSourceBase
передается в качестве аргумента дляlessFileSourceBaseFiltered
этого передается в качестве аргумента дляlessFileSourceBaseSorted
этого передается в качестве аргумента для типаMagento\Framework\Less\File\Collector\Aggregated
.Я не нашел другого вхождения
lessFileSourceBase
(илиlessFileSource
) в другом файле, кромеdi.xml
из основного модуля. Только в некоторых файлах кэша, но они не важны.Я думаю, если вы не собираетесь использовать виртуальный тип в классе PHP, а только в
di
файлах xml, вам не нужно, чтобы он выглядел как имя класса, и вы можете использовать псевдоним.Но это всего лишь спекуляция.
Будет забавно попытаться создать класс и внедрить в его конструктор экземпляр класса,
lessFileSourceBase
чтобы увидеть, как он себя ведет.источник
\Magento\Framework\Session\Generic
исходный файл на зависимый,Magento\Core\Model\Session\Storage
вместо негоStorageInterface
вы должны получить исключение «Class Magento \ Core \ Model \ Session \ Storage not Существует». Причина в том, что ObjectManager не создает экземпляр virtualType, а просто использует его, чтобы определить, какие аргументы нужно предоставить конструктору конкретного типа, на который ссылается определение virtualType (Magento\Framework\Session\Storage
для приведенного выше примера).$requestedType
представляет виртуальный тип и используется для сбора аргументов, но$type
это конкретный тип, на который virtualType отображается и используется для вызова экземпляра объекта.lessFileSourceBase
был в более простом стиле имен / классов, он не позволял бы напрямую ссылаться на другой класс php, просто для внедрения через di.xml