Neden bazı sınıflar hem yapıcılarında hem de di.xml dosyasında enjeksiyon tanımlamaktadır?


12

Bazı sınıflarda, bağımlılık enjeksiyonlarının neden iki kez beyan edildiğini anlamıyorum - bir kez di.xmlsomut sınıfın yapıcısında ve içinde.

Örneğin içinde Magento\Backend\Model\Url, di.xmlDI için tanımlanan bu tipler kümesi vardır:

<type name="Magento\Backend\Model\Url">
    <arguments>
        <argument name="scopeResolver" xsi:type="object">
Magento\Backend\Model\Url\ScopeResolver</argument>
        <argument name="authSession" xsi:type="object">
Magento\Backend\Model\Auth\Session\Proxy</argument>
        <argument name="formKey" xsi:type="object">
Magento\Framework\Data\Form\FormKey\Proxy</argument>
        <argument name="scopeType" xsi:type="const">
Magento\Store\Model\ScopeInterface::SCOPE_STORE </argument>
        <argument name="backendHelper" xsi:type="object">
Magento\Backend\Helper\Data\Proxy</argument>
    </arguments>
</type>

Ancak aynı zamanda, somut sınıfında, enjeksiyon için gerekli olan di.xml'de tanımlanan sınıflar, yapıcıda tekrar bildirilir:

<?php
    public function __construct(
        \Magento\Framework\App\Route\ConfigInterface $routeConfig,
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo,
        \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
        \Magento\Framework\Session\Generic $session,
        \Magento\Framework\Session\SidResolverInterface $sidResolver,
        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
        \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        $scopeType,
        \Magento\Backend\Helper\Data $backendHelper,
        \Magento\Backend\Model\Menu\Config $menuConfig,
        \Magento\Framework\App\CacheInterface $cache,
        \Magento\Backend\Model\Auth\Session $authSession,
        \Magento\Framework\Encryption\EncryptorInterface $encryptor,
        \Magento\Store\Model\StoreFactory $storeFactory,
        \Magento\Framework\Data\Form\FormKey $formKey,
        array $data = []
) {
    //...
}
?>

Yukarıdaki yapıcısına bakarsak, \Magento\Framework\App\Route\ConfigInterface $routeConfigörneğin, içinde tanımlanmamıştır di.xml. Sadece kurucuda tanımlanır ve Magento hala routeConfigkullanmak için sınıfa enjekte eder , değil mi? Aynı \Magento\Framework\Encryption\EncryptorInterface $encryptorve diğerleri için.

Öyleyse, neden di.xmlyapıcıda bu bildirimleri almak için Magento'nun bu bağımlılıkları kullanım için sınıfa enjekte etmek için yeterli olduğunda hem yapıcıdaki hem de kurucudaki diğer enjeksiyonları tanımlamaya ihtiyaç vardır ?

Yanıtlar:


15

Belgelerde belirtildiği gibi, Magento 2'de, di.xmlaşağıdakileri yapmak için kullanılabilir:

di.xmlBağımsız değişken düğümünde sınıf yapıcı bağımsız değişkenlerini yapılandırabilirsiniz . Nesne yöneticisi bu argümanları oluşturma sırasında sınıfa enjekte eder. XML dosyasında yapılandırılan bağımsız değişkenin adı, yapılandırılmış sınıftaki yapıcıdaki parametrenin adına karşılık gelmelidir.

Senin durumunda biraz karmaşık her argümanı tek tek açıklayacağım:

  • \Magento\Framework\App\Route\ConfigInterface $routeConfig: bu bir arabirimdir, dolayısıyla doğrudan kullanılamaz . Bu sınıf için tercih tanımlanırapp/etc/di.xml ve öyle Magento\Framework\App\Route\Configsınıf
  • \Magento\Framework\App\RequestInterface $request : aynı şey bu sınıf için de geçerli, tercih Magento\Framework\App\Request\Http
  • \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo: burada yine aynı durum Magento\Framework\Url\SecurityInfo\Proxytercih olarak
  • \Magento\Framework\Url\ScopeResolverInterface $scopeResolver: burada ilginç parça ile başlıyoruz. Gelen app/etc/di.xmlbir tercihle bu arayüz için tanımlanmış ve öyle olduğu Magento\Framework\Url\ScopeResolversınıf. Ancak, Magento\Backend\Model\UrlMagento 2 için başka bir sınıf kullanmanız gerekir ve böylece di.xmlsize hangi sınıfta bu Magento\Backend\Model\Url\ScopeResolverşekilde kullanılacağını tanımlar .
  • \Magento\Framework\Session\Generic $session bu normal bir sınıftır ve bu nedenle olduğu gibi kullanılabilir.
  • \Magento\Framework\Session\SidResolverInterface $sidResolver: bir arayüze dönersek, tercih hala tanımlanmış app/etc/di.xmlveMagento\Framework\Session\SidResolver\Proxy
  • \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory : Bu bir fabrika sınıfıdır, bu yüzden kullanılabilir.
  • \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver: geri bizim app/etc/di.xmlve tercihiMagento\Framework\Url\QueryParamsResolver
  • \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig: burada bir tercihin tanımlandığı app/etc/di.xmlve tanımlandığı başka bir durum Magento\Framework\App\Config.
  • $scopeType: burada sadece önünde sınıf olmayan bir değişken var. Modülünüz , bu değişkenin değeri olarak kullanılması gerektiğini di.xmlbelirtir Magento\Store\Model\ScopeInterface::SCOPE_STORE. **
  • \Magento\Backend\Helper\Data $backendHelper: burada bu sınıfı bu şekilde kullanabilirdik. Bu sınıf mutlaka kullanılıyor olmamasından dolayı burada bir proxy kullanılır (: vekil sınıfları hakkında ayrıntılar için bu yayını göremez Magento 2:? Bir vekil sınıftır ne pratik açıklama )
  • \Magento\Backend\Model\Menu\Config $menuConfig : bu sınıfı olduğu gibi kullanabiliriz.
  • \Magento\Framework\App\CacheInterface $cache: app/etc/di.xmlBu arayüz için tanımlanan başka bir tercih olanMagento\Framework\App\Cache\Proxy
  • \Magento\Backend\Model\Auth\Session $authSession: yine burada aynı şekilde sınıfı kullanabilirdik, ancak tembel yükleme için bir proxy sınıfı kullanıyoruz.
  • \Magento\Framework\Encryption\EncryptorInterface $encryptor: app/etc/di.xmltekrar atlamak ve Magento\Framework\Encryption\Encryptorbir tercih olarak görüyoruz
  • \Magento\Store\Model\StoreFactory $storeFactory : bir fabrika böylece kullanabilirsiniz.
  • \Magento\Framework\Data\Form\FormKey $formKey: burada Magento\Framework\Data\Form\FormKey\Proxytembel yükleme için tekrar bir proxy sınıfı kullanıyoruz .
  • array $data = []: Bu her zaman en son gelir ve otomatik olarak boş bir dizi varsayılan olarak burada daha fazla bilgi bulabilirsiniz: Magento 2: $ data array constructor parametresi nedir?

Özetlemek

Genel olarak, sınıf yapıcılarının parametreleri arabirimlerdir veya somutlaştırılamaz sınıflardır. Böylece di.xml, her sınıf yapıcısı için kullanmak istediğiniz bağımlılıkları uyarlamanıza izin verir. Anlık sınıflar için de geçerlidir. Örneğin, bir ürün sınıfını yapıcı bağımsız değişkeni olarak alan bir sınıf yapıcısı. Yapılandırılabilir ürün modülünde uyarlanabilir, bu nedenle bağımsız değişken olarak yapılandırılabilir bir ürün sınıfı alır.


Bir arabirim parametresi için her zaman bir tercih gerekli midir? Bir yedek olarak görülebilir mi? Konfigürasyonda hiçbir yerde tercih yapmadan somut bir argüman tanımlamak anlamlı mı? Yoksa bu mümkün değil mi?
robsch

6

Bağımlılıkların tanımı ve bağımlılıkların yapılandırılması arasındaki farkı anlamak önemlidir .

Bağımlılıklar di.xml içinde tanımlanmamıştır. Bağımlılıklar , ilgili sınıfın yapıcısının içinde, belirli bir bağımlılığın türü olarak bir arabirim, bir özet veya bir fabrika belirtilerek tanımlanır , örneğin $routeConfigtürün bağımlılığıdır \Magento\Framework\App\Route\ConfigInterface.

Öte yandan, di.xmlbağımlılıkları<preference/> düğümler ve / veya xpath:type/arguments/argumentdüğümler (bazen <virtualType/>veya gibi daha gelişmiş yapılandırma düğümleri ile birlikte) kullanarak yapılandırmak için bir yerdir<proxy/> . Bağımlılığı yapılandırmak, bir nesnenin yapıcı argümanını bir uygulama / nesne / somutla eşlemek anlamına gelir .

Bağımlılıkların di.xml aracılığıyla yapılandırılabilir olmasını istersiniz, böylece bunları değiştirebilir ve belirli koşullar altında belirli bir arabirim veya bağımsız değişken için farklı bir uygulama kullanabilirsiniz (belirli koşulların ne anlama geldiğini anlamak için örneği okumaya devam edin).

Örneğin, uzantınızı geliştirirken önce yeni bir sınıf oluşturursunuz (bu yeni sınıfa bir uygulama diyoruz ). Yeni sınıfınız \Magento\Framework\App\Route\ConfigInterfacearayüzü uygular ve kendi içinde arayüz sözleşmesini onurlandıran somut bir işleve sahiptir. Şimdi yapılandırma bölümünü başlatır : Magento'ya yeni tanımlanmış uygulamanızı kullanmasını söylemek için bu uygulamayı nesneye bağımlı olarak yapılandırmanız gerekir Magento\Backend\Model\Url. Bu yapılandırmayıdi.xml dosyaların veya modülünüzün içinde yaparsınız . Bu durumda <preference/>, arayüzü yeni uygulamanızla eşlemek için düğümü kullanmanız gerekir . Diğer zamanlarda daha ayrıntılı xpath:type/arguments/argument di.xmldüğümü kullanmak içinBir betonun yalnızca belirli argümanlarını (diğer bir deyişle bağımlılıklar, diğer bir deyişle arayüzler) belirli uygulamalarla eşleyin . Şimdi, uygulamanız yalnızca \Magento\Backend\Model\Url belirli koşullarda nesne için bir bağımlılık olarak aktif olacaktır , örneğin, geçerli uygulama isteğinin kod yürütme akışında bir tür nesne Magento\Backend\Model\Urlyaratılıyor ve bunun adı verilen yapıcı tanımlı bağımlılık için bir uygulamaya ihtiyacı $routeConfigvar. tür \Magento\Framework\App\Route\ConfigInterface.

Söylemeye benzer:

"Hey Mr. ObjectManager! Her türden bir nesne örneği Magento\Backend\Model\Urlistendiğinde, lütfen önce sınıf yapıcı tanımına bir göz atın ve orada tanımlanan bağımlılıkları analiz edin . Daha sonra di.xml, geçerli HTTP isteğinin birleştirilmiş son yapılandırmasına bakmanızı istiyorum. her için yapılandırılan bağımlılık olduğu belirlenen içinde Magento \ Arka Uç \ Modeli \ URL sınıf yapıcısı . bana verip o bağımlılık uygulamasını yapılandırdı."

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.