Belajar Inject dan Component pada Dagger 2 Menggunakan Kotlin

Belajar Inject dan Component pada Dagger 2 Menggunakan Kotlin

Assalamu'alaikum Warahmatullahi Wabarakatuh.

Alhamulillah senang rasanya bisa kembali menulis dan berbagi ilmu bersama kalian, pada tutorial sebelumnya kita sudah membahas mengenai penggunaan dasar dari Dependency Injection pada pemrograman Kotlin, lanjut pada seri berikutnya yaitu disini kita menggunakan LIbrary Dagger 2 untuk memudahkan kita saat menerapkan konsep DI tersebut.

Library tersebut sangat populer dan banyak digunakan oleh professional Android Developer seluruh dunia karena fungsi dan manfaatnya dapat membantu developer untuk menerapkan konsep DI, karena DI sangatlah penting di kuasai oleh developer agar koding yang kita buat lebih efisien dan mudah untuk di Maintance.

Disini saya tidak akan membahas atau menjelaskan apa itu Dependency Injection, karena materi tersebut sudah saya bahas pada postingan sebelumnya, jika kalian orang baru yang berkunjung pada postingan ini, kalian dapat melihat tutorial sebelumnya mengenai Dependency Injection pada Link dibawah ini

Materi yang haru kalian pelajari sebelumnya

Didalam Library Dagger 2 banyak sekali Anotasi-anotasi yang dapat kalian gunakan untuk memudahkan penerapan konsep ID, seperti @Inject, @Component, @Provide, @Scope, @Module, dll. Banyak sekali anitasi yang dapat kita gunakan, disini kita akan bahas satu-per-satu, pertama kita akan membahas mengenai mengenai penggunaan Anotasi Inject dan Component.

Agar lebih mudah untuk dipahami, kita akan membuat contoh project yang sangat sederhana dengan menerapkan konsep DI, didalam project tersebut nantinya hanya akan menampilkan data String pada layar, View yang digunakan pun hanya Button dan TextView saja.

Contoh Penerapan Dependency Injection (Tanpa Dagger 2)

Contoh kasus misalnya kita memuat beberpa class, seperti Senjata, DarkKnght dan LightKnight. Berikut ini merupakan contoh kode pada tutorial saya sebelumnya dengan menggunakan Manual Dependency (Tanpa Dagger 2).

Senjata.java
package com.wildan.belajardi

//Class ini nantinya akan diakses oleh Class LightKnight dan DarkNight
class Senjata(private val namaPedang: String, private val namaTombak: String) {

    //Membuat 2 Buah Fungsi yang Mengenbalikan Nilai String dengan Data Berbeda
    fun tombak(): String {
        return namaTombak
    }

    fun pedang(): String {
        return namaPedang
    }
}
DarkKnght.java
package com.wildan.belajardi

//Membuat Constructor untuk menerima objek dari class Senjata
class DarkKnight (private val senjata: Senjata) {

    //Membuat Fungsi yang Mengembalikan Nilai String
    fun setEquip(): String {
        return "Kolempok DarkKnight Bertempur Menggunakan " + senjata.tombak()
    }
}
LightKnight.java
package com.wildan.belajardi

//Membuat Constructor untuk menerima objek dari class Senjata
internal class LightKnight (private val senjata: Senjata) {

    //Membuat Fungsi yang mengembalikan Nilai String
    fun setEquip(): String {
        return "Kolempok LightKnight Bertempur Menggunakan " + senjata.pedang()
    }
}
Pada class LightKnight dan DarkKnight terdapat constructor dengan parameter dari class Senjata, kedua class tersebut membuatuhkan Instance atau Objek dari Class Senjata untuk memanggil fungsi tombak() dan pedang().

Untuk implementasi objeknya kita buat didalam MainActivity, seperti berikut ini.
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        //Membuat variable untuk memberi nama pada senjata yang akan digunakan
        val namaPedang = "Pedang Api"
        val namaTombak = "Tombak Petir"

        //Membuat Objek dari Class Senjata dengan Parameter
        val senjata = Senjata(namaPedang, namaTombak)

        //Membuat Instance atau Objec dari Class Light dan Dark Night
        val lightKnight = LightKnight(senjata)
        val darkKnight = DarkKnight(senjata)

        //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 " + darkKnight.setEquip()
            report.text = getReport
        }
    }
}
Untuk setiap Instance atau Objek, kita cukup membuatnya didalam MainActivity saja, karena objek tersebut hanya akan di eksekusi pada MainActivity pada saat button di klik. Tapi jika se waktu-waktu objek tersebut di akses oleh class lain (selain MainActivity) pastinya kita harus membuat Objeknya lagi. Misalnya ada 5 Activity yang ingin mengakses class LightKnight dan DarkKnight pastinya repot, harus membuatnya satu per satu.

Salah satu solusi untuk mengatasi permasalahan tersebut yaitu dengan menggunakan Dagger 2, sebuah library yang dapat mengubah kode DI menjadi lebih praktis dan efsien.

Menerapkan @Inject dan @Component pada Dagger 2

Pada tahap berikutnya mari kita ubah kode program sebelumnya dengan kode program yang baru dengan meng-implementasikan Library Dagger 2. Buka file build.gradle (app module), masukan baris kode berikut ini di paling atas didalam file tersebut.
apply plugin: 'kotlin-kapt'
Setelah itu didalam dependencies nya implementasikan library berikut ini.
implementation  "com.google.dagger:dagger-android-support:2.12"
kapt "com.google.dagger:dagger-compiler:2.12"
kapt "com.google.dagger:dagger-android-processor:2.12"
Supaya lebih mudah dipahami, disini kita akan menggunakan 2 buah class yaitu LightKnight dan DarkKnight jadi class Senjata tidak akan kita gunakan dulu dan akan digunakan kembali pada tutorial selanjutnya.

1) Pada class DarkKnight dan LightKnight kita tambahkan Anotasi Inject constructor () yang berfungsi untuk menginjek konstruktor pada class tersebut, jadi nantinya pada MainActivity kita tidak perlu membuat Objet atau Instance dari class tersebut.

DarkKnght.java
import javax.inject.Inject

class DarkKnight @Inject constructor() {

    //Membuat Fungsi yang Mengembalikan Nilai String
    fun setEquip(): String {
        return "Kolempok DarkKnight Bertempur Menggunakan Tombak"
    }
}
LightKnight.java
import javax.inject.Inject

class LightKnight @Inject constructor() {

    //Membuat Fungsi yang mengembalikan Nilai String
    fun setEquip(): String {
        return "Kolempok LightKnight Bertempur Menggunakan Pedang"
    }
}
Dengan begitu pada class MainActivity kita tidak akan membuat objek seperti new LightKnight() atau new DarkKnight().

2) Selanjutnya kita perlu membuat class interface Component nya, buat class baru berinama misalnya BattleComponent. Source codenya kurang lebih seperti berikut ini.
package com.wildan.belajardi

import dagger.Component

@Component
interface BattleComponent {
    fun inject(context: MainActivity)
}
Didalam class tersebut kita menambahkan Anotasi Component yang didalamnya terdapat sebuah method bernama inject(), method ini digunakan untuk mengambil context dari activity yang akan menerma Inject yaitu MainActivity.

3) Jika sudah, jangan lupa untuk membuild ulang (Rebuild) aplikasi tersebut, agar class interface BattleComponent dapat kita panggil pada MainActivity.

4) Buka MainActivity, disini kita hanya perlu membuat Variable dari Class DarkKnight dan LightKnight, tanpa harus membuat Objek atau Instance nya. Lalu untuk mendapatkan Konteks dari MainActivity, kita cukup memanggil method inject()  dari class BattleComponent tadi.
package com.wildan.belajardi

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 darkKnight: 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 " + darkKnight!!.setEquip()
            report.text = getReport
        }
    }
}
Agar kedua class tersebut dapat digunakan, kita cukup menambahkan Anotasi Inject pada masing-masing variable dari class tersebut, karena sebelumnya kita sudah meng-inject Constructornya, jadi cukup membuat variablenya saja.

Lalu untuk menerima konteks dari MainActivity, kita cukup memanggil fungsi inject() dari class interface BattleComponent,  nama class interface tersebut akan berubah dengan penambahan kata Dagger di awal, secara otomatis saat kita rebuild tadi.

Untuk menampilkan hasilnya, kita panggil method setEquip() dari kedua class tersebut. Maka hasilnya akan seperti berikut ini.

Demo:

Screenshot_project_DI_sederhana

Semoga bermanfaat, pada tutorial selanjutnya saya akan share mengenai penggunaan Anotasi @Madule dan @Provide pada Dagger 2. Terimakasih, mohon maaf bila ada kesalahan.

Wassalamu'alaikum Warahmatullahi Wabarakatuh.

Wildan M Athoillah
Wildan M Athoillah Blogger dan spesialis pembuat aplikasi android.