Dagger 2 Menggunakan Kotlin - Penggunaan Anotasi Qualifier


Assalamu'alaikum Warahmatullahi Wabarakatuh.

Sebelumnya kita sudah mempelajari beberapa komponen inti didalam Dagger 2, seperti @Inject, @Component, @Module dan @Provides. Perlu kalian ketahui, selain keempat anotasi tersebut, ternyata ada beberapa komponen didalam library tersebut yang dapat membantu kita di belakang layar, salah satunya yaitu @Qualifier.


Secara singkat, Qualifier akan kita gunakan untuk memberi kode unik pada Instance dari class didalam method @Provides, jika pada method tersebut mengembalikan objek yang sama tetapi mempunyai nilai yang berbeda pada parameternya, maka kita bisa membedakannya dengan kode unit yang di buat menggunakan @Qualifier.

Untuk setiap studi kasusnya berbeda-beda pada setiap web di luaran sana, tapi disini saya akan menyampaikannya secara singkat dan sederhana, supaya kalian dapat dengan udah untuk memahami materi tersebut

Materi sebelumnya yang harus kalian pelajari :
  1. Tutorial Dasar Dependency Injection Pada Kotlin di Android Studio
  2. Belajar Inject dan Component pada Dagger 2 Menggunakan Kotlin
  3. Library Dagger 2 - Provides dan Module Menggunakan Kotlin

Karena project yang akan kita buat ini lanjutan dari project sebelumnya, jadi saya sarankan kalian untuk mengikuti tutorial yang telah saya berikan sebelumnya, yang dapat kalian lihat pada link di atas. Jika sudah, maka kita akan lanjut pada tutorial berikut ini.

Menerapkan @Qualifiler di Belakang Layar

Pada contoh kasus berikut ini, kita akan membuat 2 data yang berbeda didalam parameter pada class Senjata. Pertama kita akan merubah kode didalam class Module. Sebelumnya kita mempunyai kode seperti berikut ini.
import dagger.Module
import dagger.Provides

@Module
class BattleModule {

    //Menyediakan Dependenci yang akan digunakan dengan Parameter didalam Class Senjata
    @Provides
    fun setSenjata(): Senjata {
        return Senjata("Pedang Larva", "Tombak Halilintar")
    }
}
Pada method setSenjata() akan mengembalikan Instance dari Class Senjata, dengan dua parameter didalamnya. Jika kita ingin mengubah data didalam Parameter tersebut tanpa harus menghapus data sebelumnya. Misalnya seperti ini.
import dagger.Module
import dagger.Provides

@Module
class BattleModule {

    @Provides
    fun setSenjata(): Senjata {
        return Senjata("Pedang Larva", "Tombak Halilintar")
    }

    @Provides
    fun setSenjataCadangan(): Senjata {
        return Senjata("Pedang Naga", "Tombak Golem")
    }
}
Jika kita membuatnya seperti pada kode di atas, Dagger 2 akan kebingungan untuk menentukan data mana yang akan diambil dan memasukannya pada class Senjata.

Coba kalian build ulang project tersebut, maka akan terjadi error, kurang lebih seperti ini
error: com.wildan.belajardi.Senjata is bound multiple times:

Untuk mengatasi permasalahan tersebut, untuk itu kita gunakan salah satu kemampuan dari Dagger 2 yaitu Qualifier, yang akan membantu kita di belakang layar. Lalu bagaimana cara implementasinya.

1) Pertama kita perlu membuat Anotasi baru, turunan dari @Qualifier, caranya buat class interface  baru, berinama class tersebut misalnya "Choose", lalu tambahkan beberapa atribut seperti berikut ini.
import javax.inject.Qualifier

@Qualifier
@MustBeDocumented
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
annotation class Choose(val value: String = "")
Nantinya interface tersebut digunakan untuk memberi kode unik pada masing-masing method didalam class Module, kode unik tersebut mempunyai tipe data String.

2) Buka kembali class BattleModule, disini kita akan menambahkan Anotasi @Choose pada masing-masing method didalam class tersebut.
import dagger.Module
import dagger.Provides

@Module
internal object BattleModule {

    @Provides
    @Choose("SenjataUtama")
    fun setSenjata(): Senjata {
        return Senjata("Pedang Larva", "Tombak Halilintar")
    }

    @Provides
    @Choose("SenjataCadangan")
    fun setSenjataCadangan(): Senjata {
        return Senjata("Pedang Naga", "Tombak Golem")
    }
}
Disana terdapat dua buah method yang berbeda tetapi mengembalikan Instance dari class yang sama, Anotasi Choose berperan memberi kode unik yang bertujuan untuk membedakan antara method setSenjata() dan setSenjataCadangan(), agar tidak terjadi error seperti tadi.

3) Buka kembali class DarkKnight dan LightKnight, disini kita akan membuat 2 buah variable dari class Senjata dan akan memangil kedua class tersebut secara bersamaan.

DarkKnight
import javax.inject.Inject

class DarkKnight @Inject constructor(){

    @Inject
    @field:Choose("SenjataUtama")
    lateinit var senjataUtama: Senjata

    @Inject
    @field:Choose("SenjataCadangan")
    lateinit var senjataCadangan: Senjata

    //Membuat Fungsi yang Mengembalikan Nilai String
    fun setEquip(): String {
        return ("Kolempok DarkKnight Bertempur Menggunakan "
                + senjataUtama.tombak() + " dan " + senjataCadangan.tombak())
    }
}
LightKnight
import javax.inject.Inject

class LightKnight @Inject constructor() {

    @Inject
    @field:Choose("SenjataUtama")
    lateinit var senjataUtama: Senjata

    @Inject
    @field:Choose("SenjataCadangan")
    lateinit var senjataCadangan: Senjata

    //Membuat Fungsi yang mengembalikan Nilai String
    fun setEquip(): String {
        return ("Kolempok LightKnight Bertempur Menggunakan "
                + senjataUtama.pedang() + " dan " + senjataCadangan.pedang())
    }
}
Coba kalian perhatikan, didalam class tersebut kita membuat 2 buah variable dari class Senjata, dengan menggunakan anotasi @Choose, kita dapat menentukan data dari method yang akan kita pilih dari class BatteModule. Lalu kita juga mengosongkan Constructor dari kedua class tersebut dan menambahkan Anotasi @Inject constructor() di atasnya agar tidak terjadi error.

4) Pada MainActivity, source codenya tidak berbeda jauh dari kode sebelumnya, seperti berikut ini.
import android.os.Bundle
import android.support.annotation.Nullable
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

import javax.inject.Inject

class MainActivity : AppCompatActivity() {

    //Deklarasi Variable dengan menggunakan Anotasi Inject
    @Inject
    lateinit var darkNight: DarkKnight
    @Inject
    lateinit var lightKnight: LightKnight

    override fun onCreate(@Nullable savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Mendapatkan Konteks dari class yang bersangkutan
        DaggerBattleComponent.create().inject(this)

        //Menambahkan listener pada Button
        click_me.setOnClickListener {
            //Menampilkan Data pada TextView yang diambil dari Fungsi setEquip dari kedua Class tersebut
            val getReport = lightKnight.setEquip() + " dan " + darkNight.setEquip()
            report.text = getReport
        }
    }
}
Jangan lupa untuk me-rebuild project tersebut lalu jalankan dan lihatlah hasilnya.

Demo:


Pada tutorial berikutnya kita akan belajar mengenai pengunaan Anotasi @Scope pada Dagger 2 menggunakan Kotlin. Semoga bermanfaat, jika kalian mempunyai pertanyaan silakan isi kolom komentar dibawah ini. Terimakasih, mohon maaf jika ada kesalahan.

Wassalamu'alaikum Warahmatullahi Wabarakatuh.

Disqus Comments