Saya tidak mengerti mengapa, di beberapa kelas, injeksi ketergantungan mereka dideklarasikan dua kali - sekali di di.xml
dan di konstruktor kelas beton.
Misalnya dalam Magento\Backend\Model\Url
, di.xml
ini memiliki set tipe untuk DI didefinisikan:
<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>
Tetapi pada saat yang sama, dalam kelas konkretnya, kelas-kelas yang didefinisikan dalam di.xml yang diperlukan untuk injeksi dinyatakan kembali dalam konstruktor:
<?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 = []
) {
//...
}
?>
Jika kita melihat konstruktornya di atas,, \Magento\Framework\App\Route\ConfigInterface $routeConfig
misalnya, tidak didefinisikan dalam di.xml
. Itu hanya didefinisikan dalam konstruktor dan Magento masih akan menyuntikkan routeConfig
ke dalam kelas untuk digunakan, bukan? Sama untuk \Magento\Framework\Encryption\EncryptorInterface $encryptor
dan beberapa lainnya.
Lalu, mengapa ada kebutuhan untuk mendefinisikan injeksi lain di kedua di.xml
dan di konstruktor ketika memiliki deklarasi di konstruktor cukup untuk Magento untuk menyuntikkan dependensi ke dalam kelas untuk digunakan?
Penting untuk memahami perbedaan antara definisi dependensi dan konfigurasi dependensi.
Dependensi tidak didefinisikan di dalam di.xml. Dependensi didefinisikan di dalam konstruktor dari kelas masing-masing dengan menentukan antarmuka, abstrak atau pabrik sebagai jenis ketergantungan itu, misalnya
$routeConfig
ketergantungan jenis\Magento\Framework\App\Route\ConfigInterface
.Di sisi lain,
di.xml
adalah tempat untuk mengkonfigurasi dependensi dengan menggunakan<preference/>
node dan / atauxpath:type/arguments/argument
node (kadang-kadang ditambah dengan node konfigurasi yang lebih maju seperti<virtualType/>
atau<proxy/>
). Mengkonfigurasi ketergantungan berarti memetakan argumen konstruktor objek ke implementasi / objek / konkret .Anda ingin agar dependensi dapat dikonfigurasi melalui di.xml sehingga Anda dapat menukar mereka dan menggunakan implementasi yang berbeda untuk antarmuka atau argumen tertentu dalam kondisi tertentu (baca contoh untuk memahami apa yang dimaksud dengan kondisi tertentu).
Misalnya, saat mengembangkan ekstensi Anda, Anda harus membuat kelas baru (kami menyebut kelas baru ini sebagai implementasi ). Kelas baru Anda mengimplementasikan
\Magento\Framework\App\Route\ConfigInterface
antarmuka dan di dalamnya memiliki fungsi konkret yang menghormati kontrak antarmuka. Sekarang mulai bagian konfigurasi : untuk memberi tahu Magento agar menggunakan implementasi yang baru Anda tentukan, Anda harus mengonfigurasi implementasi ini sebagai ketergantungan untuk objekMagento\Backend\Model\Url
. Anda melakukan konfigurasi ini di dalamdi.xml
file atau modul Anda. Dalam hal ini Anda perlu menggunakan<preference/>
node untuk memetakan antarmuka untuk implementasi baru Anda. Lain kali Anda akan menggunakanxpath:type/arguments/argument
di.xml
node yang lebih granularhanya memetakan argumen tertentu (alias dependensi, alias antarmuka) yang konkret untuk implementasi tertentu . Sekarang, implementasi Anda hanya akan aktif sebagai dependensi untuk objek\Magento\Backend\Model\Url
dalam kondisi tertentu , misalnya, dalam aliran eksekusi kode permintaan aplikasi saat ini objek tipeMagento\Backend\Model\Url
sedang dibuat dan membutuhkan implementasi untuk dependensi yang ditentukan konstruktor$routeConfig
yang disebut jenis\Magento\Framework\App\Route\ConfigInterface
.Ini seperti mengatakan:
"Hai, Tn. ObjectManager! Setiap kali instance objek dari tipe
Magento\Backend\Model\Url
diminta, silakan lihat definisi konstruktor kelasnya terlebih dahulu dan menganalisis ketergantungan yang ditentukan di dalamnya. Saya ingin Anda kemudian mencari di dalam final, digabungdi.xml
dari HTTP saat ini yang meminta konfigurasi untuk setiap dan setiap dependensi yang dikonfigurasi yang didefinisikan dalam konstruktor kelas Magento \ Backend \ Model \ Url . Anda memberi saya implementasi dependensi yang dikonfigurasi tersebut. "sumber