Mengenal Fungsi dari Qualifier pada Dagger 2 di Android Studio


Assalamu'alaikum Warahmatullahi Wabarakatuh.

Pada materi ini, kita akan berkenalan dengan Anotasi Qualifier. Berbedan dengan Anotasi yang pernah saya bahas sebelumnya, seperti @Inject, @Module dan @Component. Anotasi Qualifier berjalan dibelakang layar, walaupun begitu, anotasi tersebut sangat membantu kita untuk menerapkan prinsip Dependency Injection.

Didalam project kita, Qualifier dapat digunakan untuk membuat anotasi baru, dimana anotasi tersebut akan digunakan pada method (yang ditandai dengan @Provides) didalam class module, untuk membedakan antara method satu dengan method lainnya, jika didalam method tersebut mengembalikan objek dari class yang sama.


Masih bingung?. Jika masih bingung kita akan mempelajarinya secara perlahan dengan peng-impementasian yang sederhana. tapi sebelum itu, jika kalian baru pertama kalian melihat postingan ini, saya sarankan untuk mempelajarinya dari awal di postingan saya sebelumnya.

Materi sebelumnya yang harus kalian pelajari :
  1. Tutorial Dasar Dependency Injection Untuk Pemula di Android Studio
  2. Tutorial Dasar Dagger 2 - Penggunaan Inject dan Component
  3. Tutorial Penggunaan Provides dan Module pada Dagger 2

Jika sudah, mari kita lanjutkan pembahasannya. Nantinya Qualifier tersetbut akan berjalan dibelakang layar walaupun bukan komponen inti dari Dagger 2, tapi sangat membantu sekali saat kita menerapkan prinsip DI.

Menerapkan @Qualifiler di Belakang Layar

Disini kita akan melanjutkan project sebelumnya, dengan menerapkan Qualifier ini, kita akan membuat 2 data yang berbeda didalam parameter pada class Senjata. Kode yang akan kita ubah yaitu pada class Module. Sebelumnya kita mempunyai kode seperti berikut ini.
import dagger.Module;
import dagger.Provides;

@Module
class BattleModule {
    
    @Provides
    Senjata setSenjata(){
        return new Senjata("Pedang Larva", "Pedang Halilintar");
    }
}
Didalam method setSenjata() akan mengembalikan Instance dari Class Senjata, dengan parameter didalamnya. Jika kita ingin mengubah data didalam Parameter tersebut tanpa harus menghapus data sebelumnya. Misalnya seperti ini.
@Module
class BattleModule {

    @Provides
    Senjata setSenjata(){
        return new Senjata("Pedang Larva", "Tombak Halilintar");
    }

    @Provides
    Senjata setSenjataCadangan(){
        return new Senjata("Pedang Naga", "Tombak Golem");
    }
}
Kedua method tersebut mempunyai Objek yang sama tapi dengan Nilai yang berbeda didalam parameternya, apakah bisa seperti itu?. Tentu saja tidak bisa, karena 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:

Lalu solusinya bagaimana?. Solusinya dengan menggunakan salah satu anotasi ajaib dari Dagger 2 yaitu Qualifier, yang merupakan pahlawan di belakang layar. Lalu bagaimana cara implementasinya. Silakan kalian simak tutorial dibawah ini.

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;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Qualifier
@Documented
@Retention(RUNTIME)
@interface Choose{
    String value() default "";
}
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.java, disini kita akan menambahkan Anotasi @Choose pada masing-masing method didalam class tersebut.
import dagger.Module;
import dagger.Provides;

@Module
class BattleModule {

    @Provides @Choose("SenjataUtama")
    static Senjata setSenjata(){
        return new Senjata("Pedang Larva", "Tombak Halilintar");
    }

    @Provides @Choose("SenjataCadangan")
    static Senjata setSenjataCadangan(){
        return new 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.java dan LightKnight.java, disini kita akan membuat 2 buah variable dari class Senjata dan akan memangil kedua class tersebut secara bersamaan.

DarkKnight.java
import javax.inject.Inject;

class DarkKnight {

    @Inject @Choose("SenjataUtama")
    Senjata senjataUtama;

    @Inject @Choose("SenjataCadangan")
    Senjata senjataCadangan;

    @Inject
    DarkKnight() {}

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

class LightKnight{

    @Inject @Choose("SenjataUtama")
    Senjata senjataUtama;

    @Inject @Choose("SenjataCadangan")
    Senjata senjataCadangan;

    @Inject
    LightKnight(){}

    //Membuat Fungsi yang mengembalikan Nilai String
    String setEquip(){
        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.java. Lalu kita juga mengosongkan Constructor dari kedua class tersebut dan menambahkan Anotasi @Inject di atasnya agar tidak terjadi error.

4) Pada MainActivity.java, source codenya tidak berbeda jauh dari kode sebelumnya, seperti berikut ini.
public class MainActivity extends AppCompatActivity {

    //Deklarasi Variable dengan menggunakan Anotasi Inject
    @Inject DarkKnight darkNight;
    @Inject LightKnight lightKnight;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Deklarasi dan Inisialisasi View
        final TextView reportBattle = findViewById(R.id.report);
        Button startBattle = findViewById(R.id.click_me);

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

        //Menambahkan listener pada Button
        startBattle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Menampilkan Data pada TextView yang diambil dari Fungsi setEquip dari kedua Class tersebut
                String getReport = lightKnight.setEquip() + " dan " + darkNight.setEquip();
                reportBattle.setText(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. Semoga bermanfaat, jika kalian mempunyai pertanyaan silakan isi kolom komentar dibawah ini. Terimakasih, mohon maaf jika ada kesalahan.

Wassalamu'alaikum Warahmatullahi Wabarakatuh.

Disqus Comments