No di.xml
que vem com o Magento2, há um nó type
e um nó virtualType
. Minhas perguntas é o que é isso virtualType
e, em que caso deve ser usado em vez de type
?
Em alguns lugares, parece um link simbólico ou reescreve:
<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">
Onde um caminho completo é alterado para outro, mas em outros lugares, parece ser usado como uma maneira de definir um apelido mais curto.
<virtualType name="lessFileSourceBase" type="Magento\Framework\View\File\Collector\Base">
magento2
dependency-injection
virtualtype
David Manners
fonte
fonte
Magento\Framework\ObjectManager\Config\Mapper\Dom::convert
. Há umaswitch
declaração lá em algum lugar.lessFileSourceBase
é limitado ao xml ou se isso também pode ser usado fora. Acho que é melhor eu cavar.Respostas:
Tipos virtuais são uma maneira de injetar diferentes dependências em classes existentes sem afetar outras classes.
Por exemplo, a
Magento\Framework\Session\Storage
classe usa um$namespace
argumento em seu construtor, cujo padrão é o valor 'padrão', e você pode usar atype
definição para alterar o espaço de nome para 'núcleo'.A configuração acima faria com que todas as instâncias
Magento\Framework\Session\Storage
tivessem um namespace 'core'. O uso de um tipo virtual permite que o equivalente a uma subclasse seja criado, onde apenas a subclasse possui os valores alterados do argumento.Na base de código, vemos as duas configurações a seguir:
O primeiro trecho cria um tipo virtual para o
Magento\Core\Model\Session\Storage
qual altera o espaço para nome e o segundo injeta o tipo virtualMagento\Framework\Session\Generic
. Isso permiteMagento\Framework\Session\Generic
ser personalizado sem afetar outras classes que também declaram uma dependência deMagento\Framework\Session\Storage
fonte
<type>
está usando uma classe virtual que realmente não existe. Dessa forma, a modificação do argumentovirtualType
entrará em vigor somente quando a classe que usa o virtualType for inicializada, comoMagento\Framework\Session\Generic
no exemploOutra maneira de entender os tipos virtuais -
Digamos que você tenha uma classe
\Class1
, que tenha o seguinte construtor -E
\Class2
tem o seguinte construtor -Agora, você deseja alterar o tipo de
$argOfClass2
de\Class3
para\Class4
, mas somente quando\Class2
é usado como$argOfClass1
.A maneira "antiga" de fazer isso seria adicionar o seguinte em
di.xml
-onde
\Class5
é o seguinte:Em vez de usar dessa maneira, você pode usar os tipos virtuais para realizar o mesmo, adicionando o seguinte a
di.xml
:Como você pode ver, o uso do tipo virtual salvou o trabalho de criação de
Class5
.Para referência adicional, sugiro ler o artigo de Alan Storm sobre tipos virtuais no Magento2 - http://alanstorm.com/magento_2_object_manager_virtual_types/
fonte
No mesmo
di.xml
arquivo, descobri quelessFileSourceBase
é passado como argumento paralessFileSourceBaseFiltered
que é passado como argumento paralessFileSourceBaseSorted
que é passado como argumento para tipoMagento\Framework\Less\File\Collector\Aggregated
.Não encontrei nenhuma outra ocorrência de
lessFileSourceBase
(oulessFileSource
) em outro arquivo, excetodi.xml
no módulo principal. Somente em alguns arquivos de cache, mas esses não são importantes.Eu acho que se você não usar o tipo virtual em uma classe PHP, mas apenas nos
di
arquivos xml, não será necessário fazê-lo parecer um nome de classe e você poderá usar um alias.Mas isso é pura especulação.
Será "divertido" tentar criar uma classe e injetar em seu construtor uma instância
lessFileSourceBase
para ver como ela se comporta.fonte
\Magento\Framework\Session\Generic
arquivo de origem em que depender, emMagento\Core\Model\Session\Storage
vez deStorageInterface
obter uma exceção 'Class Magento \ Core \ Model \ Session \ Storage não existe'. O motivo é que o ObjectManager não cria uma instância do virtualType, mas apenas o usa para determinar quais argumentos fornecer ao construtor do tipo concreto que é referenciado pela definição de virtualType (Magento\Framework\Session\Storage
para o exemplo acima).$requestedType
representa o tipo virtual e é usado para reunir argumentos, mas$type
é o tipo concreto para o qual o virtualType mapeia e é usado para a chamada de instanciação do objeto.lessFileSourceBase
estava em um estilo mais namespace \ tipo de classe, não permitiria referência direta por outra classe php, apenas para injecção através da di.xml