En el di.xml
que viene con Magento2 hay un nodo type
y un nodo virtualType
. Mi pregunta es: ¿qué es esto virtualType
y en qué caso debería usarse en lugar de type
?
En algunos lugares parece un enlace simbólico o reescribir:
<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">
Cuando una ruta completa se convierte en otra, pero en otros lugares parece usarse como una forma de definir un alias más corto.
<virtualType name="lessFileSourceBase" type="Magento\Framework\View\File\Collector\Base">
magento2
dependency-injection
virtualtype
David modales
fuente
fuente
Magento\Framework\ObjectManager\Config\Mapper\Dom::convert
. Hay unaswitch
declaración allí en alguna parte.lessFileSourceBase
se limita al xml o si eso también se puede usar afuera. Supongo que mejor me cavo.Respuestas:
Los tipos virtuales son una forma de inyectar diferentes dependencias en las clases existentes sin afectar a otras clases.
Por ejemplo, la
Magento\Framework\Session\Storage
clase toma un$namespace
argumento en su constructor, que por defecto es el valor 'predeterminado', y podría usar latype
definición para cambiar el espacio de nombres a 'núcleo'.La configuración anterior haría que todas las instancias
Magento\Framework\Session\Storage
tengan un espacio de nombres de 'núcleo'. El uso de un tipo virtual permite crear el equivalente de una subclase, donde solo la subclase tiene los valores de argumento alterados.En el código base vemos las siguientes dos configuraciones:
El primer fragmento crea un tipo virtual para el
Magento\Core\Model\Session\Storage
que altera el espacio de nombres, y el segundo inyecta el tipo virtualMagento\Framework\Session\Generic
. Esto permiteMagento\Framework\Session\Generic
ser personalizado sin afectar otras clases que también declaran una dependencia enMagento\Framework\Session\Storage
fuente
<type>
está usando una clase virtual que en realidad no existe. De esta manera, la modificación del argumentovirtualType
tendrá efecto solo cuando se inicialice la clase que usa virtualType, que esMagento\Framework\Session\Generic
en el ejemploOtra forma de entender los tipos virtuales:
Digamos que tiene una clase
\Class1
, que tiene el siguiente constructor:Y
\Class2
tiene el siguiente constructor:Ahora, desea cambiar el tipo de
$argOfClass2
de\Class3
a\Class4
, pero solo cuando\Class2
se usa como$argOfClass1
.La forma "antigua" de hacerlo sería agregar lo siguiente en
di.xml
-donde
\Class5
es lo siguiente:En lugar de usarlo de esta manera, puede usar los tipos virtuales para lograr lo mismo, agregando lo siguiente a
di.xml
:Como puede ver, usar el tipo virtual le ahorró el trabajo de creación
Class5
.Para mayor referencia, sugiero leer el artículo de Alan Storm sobre los tipos virtuales en Magento2: http://alanstorm.com/magento_2_object_manager_virtual_types/
fuente
En el mismo
di.xml
archivo encontré quelessFileSourceBase
se pasa como argumento paralessFileSourceBaseFiltered
eso se pasa como argumento paralessFileSourceBaseSorted
eso se pasa como argumento para typeMagento\Framework\Less\File\Collector\Aggregated
.No encontré ninguna otra aparición de
lessFileSourceBase
(olessFileSource
) en otro archivo, exceptodi.xml
del módulo central. Solo en algunos archivos de caché, pero no son importantesSupongo que si no va a usar el tipo virtual en una clase PHP, pero solo en los
di
archivos xml, no es necesario que parezca un nombre de clase y puede usar un alias.Pero esto es solo pura especulación.
Será "divertido" intentar crear una clase e inyectar una instancia en su constructor
lessFileSourceBase
para ver cómo se comporta.fuente
\Magento\Framework\Session\Generic
archivo de origen para dependerMagento\Core\Model\Session\Storage
deStorageInterface
él, debería obtener una excepción 'Clase Magento \ Core \ Model \ Session \ Storage no existe'. La razón es que ObjectManager no crea una instancia de virtualType, sino que solo la usa para determinar qué argumentos proporcionar para el constructor del tipo concreto al que hace referencia la definición de virtualType (Magento\Framework\Session\Storage
para el ejemplo anterior).$requestedType
representa el tipo virtual y se usa para recopilar argumentos, pero$type
es el tipo concreto al que se asigna virtualType y se usa para la llamada de instanciación de objetos.lessFileSourceBase
estuviera en un estilo de tipo de espacio de nombres \ clase más, no permitiría la referencia directa de otra clase de php, solo para inyección a través de di.xml