Dans di.xml
Magento2, il existe un nœud type
et un nœud virtualType
. Ma question est qu'est-ce que c'est virtualType
et dans quel cas devrait-il être utilisé à la place de type
?
À certains endroits, cela ressemble à un lien symbolique ou à une réécriture:
<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">
Lorsqu'un chemin complet est modifié en un autre mais qu'à d'autres endroits, il semble être utilisé pour définir un alias plus court.
<virtualType name="lessFileSourceBase" type="Magento\Framework\View\File\Collector\Base">
magento2
dependency-injection
virtualtype
David Manners
la source
la source
Magento\Framework\ObjectManager\Config\Mapper\Dom::convert
. Il y a uneswitch
déclaration quelque part.lessFileSourceBase
est limité au xml ou s'il peut également être utilisé à l'extérieur. Je suppose que je ferais mieux de creuser.Réponses:
Les types virtuels sont un moyen d'injecter différentes dépendances dans les classes existantes sans affecter les autres classes.
Par exemple, la
Magento\Framework\Session\Storage
classe prend un$namespace
argument dans son constructeur, qui prend par défaut la valeur 'default', et vous pouvez utiliser latype
définition pour modifier l'espace de nom en 'core'.La configuration ci-dessus ferait en sorte que toutes les instances de
Magento\Framework\Session\Storage
ont un espace de noms de 'noyau'. L'utilisation d'un type virtuel permet de créer l'équivalent d'une sous-classe, seule la sous-classe ayant les valeurs d'argument modifiées.Dans la base de code, nous voyons les deux configurations suivantes:
Le premier extrait crée un type virtuel pour
Magento\Core\Model\Session\Storage
lequel modifie l'espace de nom, et le second injecte le type virtuel dansMagento\Framework\Session\Generic
. Cela permetMagento\Framework\Session\Generic
d’être personnalisé sans affecter les autres classes qui déclarent également une dépendance àMagento\Framework\Session\Storage
la source
<type>
utilise une classe virtuelle qui n'existe pas réellement. De cette façon, la modification d'argumentvirtualType
ne prendra effet que lorsque la classe utilisant le virtualType sera initialisée, commeMagento\Framework\Session\Generic
dans l'exempleUne autre façon de comprendre les types virtuels -
Disons que vous avez une classe
\Class1
, qui a le constructeur suivant -Et
\Class2
a le constructeur suivant -Maintenant, vous voulez changer le type de
$argOfClass2
de\Class3
à\Class4
, mais seulement quand\Class2
est utilisé comme$argOfClass1
.La "vieille" façon de faire serait d’ajouter ce qui suit dans
di.xml
-où
\Class5
est le suivant:Au lieu d'utiliser cette méthode, vous pouvez utiliser les types virtuels pour accomplir la même chose, en ajoutant ce qui suit
di.xml
:Comme vous pouvez le constater, l’utilisation du type virtuel vous a sauvé le travail de création de
Class5
.Pour plus de référence, je suggère de lire l'article d'Alan Storm concernant les types virtuels dans Magento2 - http://alanstorm.com/magento_2_object_manager_virtual_types/
la source
Dans le même
di.xml
fichier, j'ai trouvé quelessFileSourceBase
c'est passé comme argument carlessFileSourceBaseFiltered
c'est passé comme argument carlessFileSourceBaseSorted
c'est passé comme argument pour typeMagento\Framework\Less\File\Collector\Aggregated
.Je n'ai trouvé aucune autre occurrence de
lessFileSourceBase
(oulessFileSource
) dans un autre fichier, à l'exceptiondi.xml
du module de base. Seulement dans certains fichiers de cache mais ceux-ci ne sont pas importants.Je suppose que si vous n'utilisez pas le type virtuel dans une classe PHP, mais uniquement dans les
di
fichiers xml, vous n'êtes pas obligé de faire en sorte que cela ressemble à un nom de classe et vous pouvez utiliser un alias.Mais ce n’est que pure spéculation.
Ce sera "amusant" d'essayer de créer une classe et d'injecter dans son constructeur une instance de
lessFileSourceBase
pour voir comment elle se comporte.la source
\Magento\Framework\Session\Generic
le fichier source en fonction de laMagento\Core\Model\Session\Storage
place,StorageInterface
vous devriez obtenir une exception 'Classe Magento \ Core \ Modèle \ Session \ Storage n'existe pas'. La raison étant que ObjectManager ne crée pas d'instance de virtualType, mais l'utilise simplement pour déterminer les arguments à fournir pour le constructeur du type concret référencé par la définition de virtualType (Magento\Framework\Session\Storage
pour l'exemple ci-dessus).$requestedType
représente le type virtuel et est utilisé pour rassembler des arguments, mais$type
correspond au type concret auquel mappe virtualType et est utilisé pour l'appel d'instanciation d'objet.lessFileSourceBase
était dans un style de type plus d'espace de noms \ class, cela ne permettrait pas une référence directe par une autre classe php, juste pour une injection via le di.xml