Apa yang dapat dimasukkan ke dalam mekanisme Injeksi Ketergantungan di Angular?

Hampir setiap developer Angular dapat menemukan solusi untuk masalah mereka di Dependency Injection. Ini jelas terlihat di komentar di artikel terakhir saya . Orang-orang mempertimbangkan berbagai opsi untuk bekerja dengan data dari DI, dibandingkan kenyamanan mereka untuk situasi tertentu. Ini bagus karena alat sederhana seperti itu memberi kita banyak kemungkinan.



Tetapi beberapa orang unsubscribe kepada saya sehingga sulit bagi mereka untuk memahami DI dan kemampuannya di Angular. Tidak banyak materi di Internet tentang cara menggunakan DI secara efektif, dan bagi banyak pengembang hal itu bermuara pada bekerja dengan layanan global atau meneruskan data global dari akar aplikasi ke komponen.



Mari kita lihat lebih dalam mekanisme ini di Angular.









Apakah Anda tahu kecanduan Anda?



Terkadang tidak mudah untuk memahami berapa banyak dependensi yang dimiliki kode Anda.



Misalnya, lihat pseudo-class ini dan hitung berapa banyak dependensi yang dimilikinya:



import { API_URL } from '../../../env/api-url';
import { Logger } from '../../services/logger';
 
class PseudoClass {
   request() {
       fetch(API_URL).then(...);
   }
 
   onError(error) {
       const logger = new Logger();
 
       logger.log(document.location, error);
   }
}


Menjawab
fetch β€” API, , , .



API_URL β€” ( ).



new Logger() β€” , .



document β€” API .





Jadi ada apa?



Misalnya, kelas seperti itu sulit untuk diuji karena bergantung pada data yang diimpor dari file lain dan entitas tertentu di dalamnya.



Situasi lain: dokumen dan pengambilan akan bekerja dengan lancar di browser Anda. Tetapi jika suatu hari Anda perlu mentransfer aplikasi ke Server Side Rendering, maka variabel global yang diperlukan mungkin tidak ada di lingkungan nodejs.



Jadi apa itu DI dan mengapa itu dibutuhkan?



Dependency Injection mengelola dependensi dalam aplikasi. Pada dasarnya, bagi kami, sebagai developer Angular, sistem ini cukup sederhana. Ada dua operasi utama: memasukkan sesuatu ke dalam pohon ketergantungan atau mendapatkan sesuatu darinya.



Untuk perspektif yang lebih teoritis tentang DI, baca tentang Inversi Prinsip Kontrol . Anda juga dapat menonton video menarik dengan topik: serangkaian video tentang IoC dan DI dari Ilya Klimov dalam bahasa Rusia atau video pendek tentang IoC dalam bahasa Inggris.



Semua keajaiban berasal dari urutan di mana kita menyediakan dan menerima ketergantungan.



Bagaimana cakupan bekerja di DI:





Apa yang bisa kita masukkan ke DI?



Yang pertama dari operasi DI adalah memasukkan sesuatu ke dalamnya. Sebenarnya, untuk ini, Angular memungkinkan kita untuk menulis array penyedia di dekorator modul, komponen, atau arahan kita. Mari kita lihat terdiri dari apa array ini.



Menyediakan kelas



Biasanya setiap developer Angular mengetahui hal ini. Ini adalah saat Anda menambahkan layanan ke aplikasi Anda.



Angular membuat instance kelas saat Anda pertama kali memintanya. Dan dengan Angular 6, kita tidak bisa menulis kelas dalam array provider sama sekali, tetapi memberitahu kelas itu sendiri di mana DI harus pergi dengan disediakanIn :



providers: [
   {
       provide: SomeService,
       useClass: SomeService
   },
   // Angular        :
   SomeService
]




Memberikan nilai



Nilai konstanta juga dapat diberikan melalui DI. Ini bisa berupa string sederhana dengan URL API Anda, atau Observable kompleks dengan data.



Memberikan nilai biasanya diimplementasikan bersama dengan InjectionToken . Objek ini adalah kunci untuk mesin DI. Pertama, Anda berkata: "Saya ingin mendapatkan data ini untuk kunci ini." Dan kemudian Anda datang ke DI dan bertanya: "Apakah ada sesuatu di kunci ini?"



Nah, kasus yang umum adalah penerusan data global dari root aplikasi.



Lebih baik untuk segera melihat ini beraksi, jadi mari kita lihat stackblitz dengan sebuah contoh:



Luaskan contoh






Jadi, dalam contoh, kami mendapatkan ketergantungan dari DI daripada mengimpornya sebagai konstanta dari file lain secara langsung. Dan mengapa itu lebih baik bagi kita?



  • Kita dapat mengganti nilai token pada level manapun di pohon DI tanpa mengubah komponen yang menggunakannya.
  • Kami dapat memalsukan nilai token dengan data yang sesuai saat menguji.
  • Komponen ini sepenuhnya terisolasi dan akan selalu berfungsi sama apa pun konteksnya.




Menyediakan pabrik



Menurut saya, ini adalah alat paling kuat di mesin injeksi ketergantungan Angular.



Anda dapat membuat token yang akan menjadi hasil penggabungan dan konversi nilai token lainnya.



Berikut adalah stackbitz lain dengan contoh mendetail tentang membuat pabrik dengan aliran.



Luaskan contoh






Anda dapat menemukan banyak kasus saat memberikan pabrik menghemat waktu atau membuat kode lebih mudah dibaca. Terkadang kami memasukkan dependensi ke dalam komponen hanya untuk menggabungkannya atau mengubahnya menjadi format yang sama sekali berbeda. Dalam artikel sebelumnya, saya melihat masalah ini secara lebih rinci dan menunjukkan pendekatan alternatif untuk menyelesaikan situasi seperti itu.



Menyediakan instance yang sudah ada



Bukan kasus umum, tetapi opsi ini bisa menjadi alat yang sangat berguna.



Anda dapat memasukkan entitas yang telah dibuat ke dalam token. Bekerja dengan baik dengan forwardRef .



Lihat contoh stackblitz lain dengan arahan yang mengimplementasikan antarmuka dan mengganti token lain dengan useExisting. Dalam contoh ini, kami ingin mengganti nilai token khusus DI untuk komponen turunan dari elemen yang digantung direktif. Selain itu, arahannya bisa apa saja - yang utama adalah ia mengimplementasikan antarmuka yang diperlukan.



Luaskan contoh






Trik Dekorator DI



Dekorator DI memungkinkan Anda membuat permintaan DI lebih fleksibel.



Jika Anda tidak mengetahui keempat dekorator, saya sarankan membaca artikel ini di Medium . Artikelnya dalam bahasa Inggris, tetapi ada visualisasi yang sangat keren dan mudah dipahami tentang topik tersebut.



Tidak banyak orang juga yang tahu bahwa DI dekorator dapat digunakan dalam deretan deps, yang menyiapkan argumen untuk pabrik penyedia.




providers: [
   {
     provide: SOME_TOKEN,
     /**
      *     ,  
      * [new Decorator(), new Decorator(),..., TOKEN]
      * .
      *
      *      β€˜null’,     
      * OPTIONAL_TOKEN
      */
     deps: [[new Optional(), OPTIONAL_TOKEN]],
     useFactory: someTokenFactory
   }
 ]




Pabrik Token



Konstruktor InjectionToken membutuhkan dua argumen.



Argumen kedua adalah objek dengan konfigurasi token.



Pabrik token adalah fungsi yang dipanggil saat seseorang meminta token ini untuk pertama kalinya. Di dalamnya, Anda dapat menghitung nilai standar tertentu untuk token atau bahkan mengakses entitas DI lainnya melalui fungsi injeksi.



Lihatlah contoh implementasi fungsi aliran klik tombol, tetapi kali ini di pabrik token.



Luaskan contoh






Kesimpulan



DI dalam Angular adalah topik yang luar biasa: pada pandangan pertama, tidak banyak tuas dan alat yang berbeda untuk dipelajari, tetapi Anda dapat menulis dan berbicara selama berjam-jam tentang kemungkinan dan kegunaan yang mereka berikan kepada kita.



Saya harap artikel ini memberi Anda dasar yang darinya Anda dapat menemukan solusi Anda sendiri untuk menyederhanakan bekerja dengan data di aplikasi dan perpustakaan Anda.



All Articles