Type ve virtualType arasındaki fark nedir


41

Bunun di.xmliçinde Magento2 ile gelen bir düğüm typeve bir düğüm var virtualType. Sorum şu: Bu nedir virtualTypeve bunun yerine hangi durumda kullanılmalı type?

Bazı yerlerde sembolik bir bağlantıya benziyor veya yeniden yazıyor:

<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">

Bir tam yolun başka bir yere değiştiği ancak diğer yerlerde daha kısa bir diğer adı tanımlamanın bir yolu olarak kullanıldığı görülüyor.

<virtualType name="lessFileSourceBase" type="Magento\Framework\View\File\Collector\Base">

3
Ben bile ne anlama geldiğini (henüz) hiçbir fikrim yok ama buradan kazma başlayabilirsiniz: Magento\Framework\ObjectManager\Config\Mapper\Dom::convert. Orada bir switchyerde bir açıklama var.
Marius

Thanks @Marius, ayrıca lessFileSourceBasexml ile sınırlı olup olmadığını veya bunun dışında da kullanılabileceğini merak ediyorum . Sanırım kazmaya başlasam iyi olur.
David Manners

Yanıtlar:


83

Sanal türler, diğer sınıfları etkilemeden mevcut sınıflara farklı bağımlılıklar enjekte etmenin bir yoludur.

Örneğin, Magento\Framework\Session\Storagesınıf $namespace, kurucuda 'default' değerine varsayılan olan bir argüman alır typeve ad alanını 'core' olarak değiştirmek için tanımı kullanabilirsiniz .

<type name="Magento\Framework\Session\Storage">
    <arguments>
        <argument name="namespace" xsi:type="string">core</argument>
    </arguments>
</type>

Yukarıdaki yapılandırma, tüm örneklerin Magento\Framework\Session\Storage'çekirdek' ad alanına sahip olmasını sağlar. Sanal bir tür kullanmak, yalnızca alt sınıfın değiştirilmiş argüman değerlerine sahip olduğu bir alt sınıfın eşdeğerini yaratmanıza izin verir.

Kod tabanında aşağıdaki iki konfigürasyonu görüyoruz:

<virtualType name="Magento\Core\Model\Session\Storage" type="Magento\Framework\Session\Storage">
    <arguments>
        <argument name="namespace" xsi:type="string">core</argument>
    </arguments>
</virtualType>

<type name="Magento\Framework\Session\Generic">
    <arguments>
        <argument name="storage" xsi:type="object">Magento\Core\Model\Session\Storage</argument>
    </arguments>
</type>

İlk snippet Magento\Core\Model\Session\Storage, ad alanını değiştiren sanal bir tür oluşturur ve ikincisi sanal türün içine enjekte eder Magento\Framework\Session\Generic. Bu, Magento\Framework\Session\Genericayrıca bağımlılık ilan eden diğer sınıfları etkilemeden özelleştirilebilmesini sağlarMagento\Framework\Session\Storage


Çok teşekkürler @Chris buldum nihayet biraz mantıklı gerekçe
Suman-PHP4U

Bu basit ve en iyi gösteri oldu.
Ömer

Bu cevap daha iyidir, Magento resmi doktoru
Suman-PHP4U

<type>aslında var olmayan bir sanal sınıf kullanıyor. Argüman modifikasyon bu yolu virtualTypeolan virtualType kullanarak sınıf başlatılır gerçekleşmeye başlayacaktır Magento\Framework\Session\Genericörnekteki
Arif Ahmed

21

Sanal türleri anlamanın başka bir yolu -

Diyelim ki \Class1aşağıdaki yapıcı olan bir sınıfınız var.

public function __construct(\Class2 $argOfClass1){...}

Ve \Class2aşağıdaki yapıcı var -

public function __construct(\Class3 $argOfClass2){...}

Şimdi, türünü değiştirmek istediğiniz $argOfClass2den \Class3üzere \Class4, ancak sadece \Class2olarak kullanılır $argOfClass1.

Bunu yapmanın "eski" yolu, aşağıdakileri eklemek olacaktır di.xml:

<type name="Class1">
    <arguments>
         <argument name="argOfClass1" xsi:type="object">Class5</argument>
    </arguments>
</type>

\Class5aşağıdakiler nerede :

class \Class5 extends \Class2{
    public function __construct(\Class4 $argOfClass2){...}
}

Bu şekilde kullanmak yerine, aşağıdakini ekleyerek, aynı işlemi gerçekleştirmek için sanal türleri kullanabilirsiniz di.xml:

<virtualType name="Class5" type="Class2">
    <arguments>
        <argument name="argOfClass2" xsi:type="string">Class4</argument>
    </arguments>
</virtualType>

<type name="Class1">
    <arguments>
         <argument name="argOfClass1" xsi:type="object">Class5</argument>
    </arguments>
</type>

Gördüğünüz gibi, sanal türü kullanarak sizi yaratma çalışmasından kurtardı Class5.

Daha fazla referans için, Alan Storm'un Magento2'deki sanal türlerle ilgili makalesini okumanızı öneririm - http://alanstorm.com/magento_2_object_manager_virtual_types/


1
iyi bir genişleme,
Anand Ontigeri

Anlaması kolay. Böyle basit bir örneği paylaştığınız için teşekkür ederiz.
Kalyan Chakravarthi V,

10

Aynı di.xmldosyada lessFileSourceBasebunun bir argüman olarak iletildiğini buldum, bunun için bir argüman lessFileSourceBaseFilteredolarak iletildi, bunun için lessFileSourceBaseSortedde bir argüman olarak yazın Magento\Framework\Less\File\Collector\Aggregated.

Çekirdek modül dışında başka bir dosyada lessFileSourceBase(veya lessFileSource) başka bir şey bulamadım di.xml. Sadece bazı önbellek dosyalarında ancak bunlar önemli değildir.

Sanal sınıfı bir PHP sınıfında kullanmayacaksanız, ancak yalnızca dixml dosyalarında kullanmanız gerekecek, sanırım bir sınıf adı gibi görünmeniz gerekmez ve bir takma ad kullanabilirsiniz.

Ama bu sadece saf spekülasyon.
Bir sınıf yaratmayı denemek ve kurucusuna lessFileSourceBasenasıl davrandığını görmek için bir örnek enjekte etmek "eğlenceli" olacaktır .


1
fun kelimesinin etrafındaki alıntıları kaçırdın;)
David Manners

1
@DavidManners. Sağ. Onardım. :)
Marius

@Marius: Eğer \Magento\Framework\Session\Generickaynak dosyasını bağımlı kalmak Magento\Core\Model\Session\Storageyerine değiştirirseniz StorageInterface, 'Class Magento \ Core \ Model \ Session \ Storage yok' istisnası almalısınız. Bunun nedeni, ObjectManager'ın virtualType örneğini yaratmaması değil, yalnızca virtualType tanımı tarafından referans verilen somut türün yapıcısı için hangi argümanları sağlayacağını belirlemek için kullanır ( Magento\Framework\Session\Storageyukarıdaki örnek için).
Chris O'Toole,

Fabrika bu görebiliyor , $requestedTypesanal tipini temsil eder ve argümanları toplamak için kullanılır, ancak $typevirtualType eşleştiren ve nesne örnekleme çağrısı için kullanıldığını somut türüdür.
Chris O'Toole,

Yani lessFileSourceBasedaha namepace \ class type tarzında olsa bile, başka bir php sınıfı tarafından doğrudan başvuru yapılmasına izin vermeyecekti, sadece di.xml yoluyla enjeksiyon için
Chris O'Toole,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.