Belati 2 adalah Dasar (Bagian 2)

Bagian sebelumnya

Isi

  1. Terapkan metode dan bidang
  2. Inisialisasi tertunda dalam belati
  3. Modul belati. Ketika belati tidak mengerti Anda
  4. Abstrak Bernama. Banyak contoh dengan tipe yang sama

Terapkan metode dan bidang

Bagian pertama menjelaskan metode untuk menerapkan ketergantungan pada tingkat konstruktor. Selain itu, belati dapat menerapkan dependensi untuk bidang dan metode. Tetapi implementasi ini harus digunakan ketika benar-benar diperlukan.

Contoh penerapan metode:

class Car @Inject constructor(private var engine: Engine){ var key: Key? = null @Inject set } class Key @Inject constructor() 

Dalam contoh di atas, ketergantungan metode set diterapkan untuk bidang kunci

Implementasi bidang berlangsung dalam tiga tahap:

  1. Tambahkan metode sematan ke pabrik abstrak
  2. Tentukan bidang yang akan diterapkan
  3. Gunakan metode implementasi dalam implementasi kelas belati abstrak untuk mengimplementasikan dependensi

Jelas akan lebih mudah untuk memahami hal ini

1. Di kelas abstrak kami, tambahkan metode implementasi untuk MainActivity

 @Component interface DaggerComponent { fun getCar(): Car fun getEngine(): Engine fun getFuel(): Fuel fun inject(act: MainActivity) } 

2. Tentukan bidang yang harus diimplementasikan dalam MainActivity. Bidang yang diinjeksi harus lateinit var dan dapat dilihat oleh semua orang (publik)

 @Injected lateinit var car: Car 

3. Kami memanggil metode menambahkan suntikan () dari kelas abstrak untuk mengimplementasikan bidang aktivitas.

Pada akhirnya, kelas MainActivity kami akan terlihat seperti jejak. cara:

 class MainActivity : AppCompatActivity() { @Inject lateinit var car: Car override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerDaggerComponent.create().inject(this) } } 

Inisialisasi tertunda dalam belati

Seperti yang Anda ketahui, saat memulai aplikasi, instance dari semua kelas tidak selalu diperlukan. Ini mempercepat peluncuran pertama dan banyak lagi. Ada 2 jenis inisialisasi objek tertanam di belati: Penyedia <> Dan Malas <>

Penyedia - inisialisasi terjadi pada panggilan pertama ke objek dan dengan setiap panggilan instance baru dari objek akan dikembalikan
Malas - inisialisasi terjadi pada panggilan pertama, lalu instance yang sebelumnya di-cache dikembalikan

Untuk menggunakan jenis inisialisasi ini, perlu "membungkus" objek yang diinisialisasi dalam bentuk yang diinginkan.

Contoh Penggunaan Penyedia:

 class Engine @Inject constructor(private var fuel: Fuel){ fun start(){ if(fuel!=null){ print("Started!") }else{ print("No more fuel!") } } } class Car @Inject constructor(private var engine: Provider<Engine>){ var key: Key? = null @Inject set fun startCar(){ engine.get().start() } } class Key @Inject constructor() 

Setiap kali metode get () dipanggil, kita mendapatkan instance baru dari objek yang diinginkan.

Contoh menggunakan Malas:

 class Fuel @Inject constructor() { val fuelType = if(BuildConfig.DEBUG){ "benzine" }else{ "diesel" } } class Engine @Inject constructor(private var fuel: Lazy<Fuel>){ fun start(){ if(fuel!=null){ print("Started with ${fuel.get().fuelType}") }else{ print("No more fuel!") } } } 

Setiap kali metode get () dipanggil, kita mendapatkan instance yang sama.

Perhatian! Saat menambahkan metode get () dari tampilan Malas di Android Studio, metode tersebut dapat digarisbawahi dengan warna merah sejak itu Kotlin memiliki kelas Malas sendiri. Jadi kami mengimpor kelas belati

 import dagger.Lazy 

Modul belati. Ketika belati tidak mengerti Anda

Ada kalanya belati tidak memahami niat Anda. Misalnya, kelas Mobil kami memiliki bidang tipe (antarmuka) Driver, yang diwarisi oleh kelas Ivanov

Ketika Anda mencoba menerapkan bidang dengan tipe antarmuka, Anda mendapatkan kesalahan "tidak dapat diberikan tanpa metode @ Memberi-anotasi".

Untuk mengatasi masalah ini, belati menyarankan menggunakan Modul. Modul memberi belati dengan informasi tambahan yang tidak bisa didapatkan sendiri. Sebagai modul, Anda dapat menggunakan antarmuka atau objek (objek).

Untuk mengatasi masalah di atas, buat modul:

 @Module interface DaggerModul { @Binds fun bindDriver(driver: Ivanov): Driver } class Ivanov @Inject constructor(): Driver 

Dalam metode bindDriver, kami menjelaskan kepada belati bagaimana menginisialisasi antarmuka.

Juga di komponen Anda perlu mendaftar semua modul belati yang ada

 @Component(modules = [DaggerModul::class]) interface DaggerComponent { … } 

Misalkan untuk Mesin kelas kami, bidang silinder perpustakaan pihak ketiga (antarmuka) digunakan. Bagaimana cara menggambarkan bidang untuk belati jika tidak jelas kelas mana yang akan diinisialisasi dalam runtime?

Sejauh ini, kami telah menggunakan anotasi untuk menjelaskan kepada belati bagaimana ketergantungan harus disuntikkan. Bagaimana jika Anda tidak tahu cara membuat kelas dari perpustakaan asing, misalnya?

Memberikan penjelasan menjelaskan kasus-kasus tersebut ketika Anda perlu menjelaskan secara eksplisit instance kelas mana yang ingin Anda inisialisasi.

 @Module object DaggerModuleObject { @Provides @JvmStatic fun getBoschCylinder(): Cylinder = BoschCylinder() } 

Jadi, kami memberi tahu belati bahwa ketika menginisialisasi bidang silinder, kami membutuhkan turunan dari kelas BoschCylinder.

Abstrak Bernama . Banyak contoh dengan tipe yang sama

Ada kalanya Anda perlu membuat instance dari kelas yang sama dengan pengaturan yang berbeda. Dalam contoh kita, ini adalah warna berbeda pada tubuh dan pintu.

Ketika mencoba membangun proyek dengan jejak. Modul akan mendapatkan kesalahan "(kelas kami) Warna terikat beberapa kali"

 @Provides @JvmStatic fun getColorRed():Color = Color("red") @Provides @JvmStatic fun getColorBlue():Color = Color("blue") 

Untuk mengatasi kasus tersebut, anotasi Bernama digunakan. Pertama-tama, dalam modul kita akan membuat 3 metode baru untuk inisialisasi dalam belati

 @JvmStatic @Provides fun getColor(): Color = Color("") @Provides @Named("blueColor") @JvmStatic fun getColorBlue(): Color{ return Color("blue") } @JvmStatic @Named("redColor") @Provides fun getColorRed(): Color = Color("red") 

Metode pertama adalah default, tanpanya belati akan bersumpah tentang tidak adanya kelas "tidak dapat disediakan tanpa konstruktor Suntik atau metode Provides-annotated"

Dua metode berikut mengembalikan instance dari kelas yang sama. Tetap menambahkan implementasi kelas ini di tempat yang tepat dan menelepon dengan anotasi yang bernama

 class Door @Inject constructor() { @Named("blueColor") @Inject lateinit var color:Color } class Car @Inject constructor(private var engine: Provider<Engine>, private var door: Door, var driver: Driver){ var key: Key? = null @Inject set @Inject @Named("redColor") lateinit var color: Color fun startCar(){ engine.get().start() } } class Key @Inject constructor() 

Kode sumber

Source: https://habr.com/ru/post/id466769/


All Articles