Apa tujuan dari disediakannya dekorator Suntik ketika menghasilkan Layanan di Angular 6?

136

Ketika menghasilkan layanan di CLI Angular, itu menambahkan metadata tambahan dengan properti 'disediakan' dengan default 'root' untuk dekorator injeksi.

@Injectable({
  providedIn: 'root',
})

Apa sebenarnya yang disediakan di lakukan? Saya berasumsi ini membuat layanan tersedia seperti layanan singleton tipe 'global' untuk seluruh aplikasi, namun, tidak akan lebih bersih untuk mendeklarasikan layanan seperti itu dalam array penyedia AppModule?

MEMPERBARUI:

Untuk orang lain, paragraf berikut memberikan penjelasan yang baik tentang itu juga, khususnya jika Anda ingin memberikan layanan Anda hanya ke modul fitur.

Sekarang ada cara baru, yang disarankan, untuk mendaftarkan penyedia, langsung di dalam @Injectable()dekorator, menggunakan providedIn atribut baru . Ini menerima 'root'sebagai nilai atau modul aplikasi Anda. Saat Anda menggunakan 'root', Anda injectableakan terdaftar sebagai singleton dalam aplikasi, dan Anda tidak perlu menambahkannya ke penyedia modul root. Demikian pula, jika Anda menggunakan providedIn: UsersModule, injectableterdaftar sebagai penyedia UsersModuletanpa menambahkannya ke providersmodul. "- https://blog.ninja-squad.com/2018/05/04/what-is-new-angular -6 /

PEMBARUAN 2:

Setelah penyelidikan lebih lanjut, saya memutuskan hanya berguna untuk memilikinya providedIn: 'root'

Jika Anda ingin providelayanan dalam modul apa pun selain modul root, maka Anda lebih baik menggunakan providersarray di dekorator modul fitur, jika tidak, Anda akan terganggu dengan dependensi melingkar. Diskusi menarik bisa didapat di sini - https://github.com/angular/angular-cli/issues/10170

Stefan Zvonar
sumber
17
Saya pikir pembaruan Anda harus menjadi jawaban (Anda dapat menjawab pertanyaan Anda sendiri) alih-alih menambahkannya ke pertanyaan Anda.
PhoneixS
Bagian yang paling penting adalah SINGLETON, tidak ada yang menyebutkannya!
Kyle Burkett

Jawaban:

54

jika Anda menggunakan providedIn, suntikan terdaftar sebagai penyedia Modul tanpa menambahkannya ke penyedia modul.

Dari Docs

Layanan itu sendiri adalah kelas yang dihasilkan CLI dan yang dihiasi dengan @Injectable. Secara default, dekorator ini dikonfigurasikan dengan properti In yang disediakan, yang membuat penyedia layanan. Dalam hal ini, asalkan Dalam: 'root' menentukan bahwa layanan harus disediakan dalam injektor root.

Sajeetharan
sumber
4
Terima kasih Sajeetharan. Oke, jadi sepertinya ini cara pintas baru untuk menentukan di mana layanan harus disediakan. Saya kira preferensi awal saya akan melihat daftar penyedia modul untuk melihat semua layanan yang dinyatakan sebagai penyedia, daripada meneliti basis kode yang tersebar untuk tag ProvidedIn .... (?)
Stefan Zvonar
2
Apakah ada alasan bagi Angular untuk menambahkan ini? Apakah ada masalah yang sedang dipecahkan? Saya tidak melihat ada alasan untuk ini.
prolink007
3
Menyimpan definisi AppModule / CoreModule sedikit lebih kecil;)
Stefan Zvonar
22
@ prolink007. Menggunakan yang disediakan pada memungkinkan layanan untuk menjadi malas-sarat oleh aplikasi. Untuk menguji ini, masukkan log konsol di layanan Anda. Halaman rumah saya digunakan untuk memuat 16 layanan, sekarang memuat 9. Sulit untuk mengukur kinerja, tetapi saya merasa lebih baik mengetahui bahwa saya tidak memuat layanan sampai mereka diperlukan :).
Stevethemacguy
3
Anda dapat membuat layanan Anda mudah diguncang dengan menggunakan providedInatribut untuk menentukan di mana layanan harus diinisialisasi saat menggunakan @Injectable()dekorator. Maka Anda harus menghapusnya dari atribut penyedia NgModuledeklarasi Anda serta pernyataan impornya. Ini dapat membantu mengurangi ukuran bundel dengan menghapus kode yang tidak digunakan dari bundel.
nircraft
48

providedIn: 'root' adalah cara termudah dan paling efisien untuk menyediakan layanan sejak Angular 6:

  1. Layanan ini akan tersedia secara luas sebagai aplikasi tunggal tanpa perlu menambahkannya ke array penyedia modul (seperti Angular <= 5).
  2. Jika layanan ini hanya digunakan dalam modul malas dimuat, maka akan malas dimuat dengan modul itu
  3. Jika tidak pernah digunakan itu tidak akan terkandung dalam membangun (pohon goyang).

Untuk informasi lebih lanjut, pertimbangkan membaca dokumentasi dan FAQ NgModule

Btw:

  1. Jika Anda tidak ingin singleton aplikasi-lebar gunakan array penyedia komponen.
  2. Jika Anda ingin membatasi ruang lingkup sehingga tidak ada pengembang lain yang akan menggunakan layanan Anda di luar modul tertentu, gunakan providersarray dari NgModule sebagai gantinya.
Mick
sumber
37

Dari Documents

Apa dekorator injeksi?

Menandai kelas sebagai tersedia untuk Injector untuk pembuatan.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

Layanan itu sendiri adalah kelas yang dihasilkan CLI dan yang didekorasi dengan @Injectable ().

Apa sebenarnya yang disediakan di lakukan?

Menentukan injeksi mana yang akan memberikan injeksi, dengan mengaitkannya dengan @NgModule atau InjectorType lainnya, atau dengan menentukan bahwa injeksi ini harus disediakan dalam injector 'root', yang akan menjadi injector tingkat aplikasi di sebagian besar aplikasi.

providedIn: Type<any> | 'root' | null

asalkan dalam: 'root'

Saat Anda menyediakan layanan di tingkat akar, Angular membuat satu contoh layanan bersama dan menyuntikkannya ke kelas apa pun yang memintanya. Mendaftarkan penyedia di @adjectable () metadata juga memungkinkan Angular untuk mengoptimalkan aplikasi dengan menghapus layanan dari aplikasi yang dikompilasi jika tidak digunakan.

disediakan dalam: modul

Dimungkinkan juga untuk menentukan bahwa layanan harus disediakan dalam @NgModule tertentu. Misalnya, jika Anda tidak ingin layanan tersedia untuk aplikasi kecuali mereka mengimpor modul yang Anda buat, Anda dapat menentukan bahwa layanan tersebut harus disediakan dalam modul

import { Injectable } from '@angular/core';
import { UserModule } from './user.module';

@Injectable({
  providedIn: UserModule,
})
export class UserService {
}

Metode ini lebih disukai karena memungkinkan Tree-shaking ( Tree shaking adalah langkah dalam proses build yang menghapus kode yang tidak digunakan dari basis kode ) layanan jika tidak ada yang menyuntikkannya.

Jika tidak mungkin untuk menentukan dalam layanan mana modul harus menyediakannya, Anda juga dapat mendeklarasikan penyedia untuk layanan dalam modul:

import { NgModule } from '@angular/core';
import { UserService } from './user.service';

@NgModule({
  providers: [UserService],
})
export class UserModule {
}
Nipuna
sumber
4
Penjelasan terbaik.
nop
2
jawaban ini lebih baik daripada definisi dalam angular doc. sangat jelas.
Shameera Anuranga
2
Dijelaskan dengan baik, Terima kasih banyak!
Zaki Mohammed
Bagaimana kalau kosong, misalnya @Injectable()?
Ben Taliadoros
13

asalkan memberitahu Angular bahwa injektor root bertanggung jawab untuk membuat turunan dari Layanan Anda. Layanan yang disediakan dengan cara ini disediakan secara otomatis untuk seluruh aplikasi dan tidak perlu dicantumkan dalam modul apa pun.

Kelas layanan dapat bertindak sebagai penyedia mereka sendiri dan itulah sebabnya mendefinisikan mereka di dekorator @Injectable adalah semua pendaftaran yang Anda butuhkan.

Jawad Farooqi
sumber
4

Menurut Documentation:

Mendaftarkan penyedia di @adjectable () metadata juga memungkinkan Angular untuk mengoptimalkan aplikasi dengan menghapus layanan dari aplikasi yang dikompilasi jika tidak digunakan.

Maarti
sumber