A simple Dagger2 example involving a single module.
It is a simple application using Dagger2 code>@Component</code. It just defines a simple one code>@Module</code.
Step 1: Install Dagger2
In your dependencies add Dagger2
and Timber2
among your dependencies:
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'com.google.dagger:dagger:2.21'
kapt ' com.google.dagger: dagger-compiler: 2.21 '
Step 2: Design Layout
Design your xml layout as follows:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Step 3: Initialize Timber
Timber is our Logging library. Initialize inside our Application
class:
App.kt
package com.star_zero.sample.dagger_tutorial.step1
import android.app.Application
import timber.log.Timber
class App : Application() {
override fun onCreate() {
super.onCreate()
Timber.plant(Timber.DebugTree())
}
}
Step 4: Create Repository classes
(a). UserRepository.kt
Create an Interface
with one function that returns a String
:
package com.star_zero.sample.dagger_tutorial.step1.data.repository
interface UserRepository {
fun getName(): String
}
(b). UserDataRepository.kt
Implement the UserRepository
aond override the getName()
function:
package com.star_zero.sample.dagger_tutorial.step1.data.repository
class UserDataRepository(private val baseURL: String) : UserRepository {
override fun getName(): String {
return "Sample Name, baseURL=$baseURL"
}
}
Step 5: Create App Module and Component:
(a). AppModule.kt
package com.star_zero.sample.dagger_tutorial.step1.di
import com.star_zero.sample.dagger_tutorial.step1.data.repository.UserDataRepository
import com.star_zero.sample.dagger_tutorial.step1.data.repository.UserRepository
import dagger.Module
import dagger.Provides
@Module
class AppModule(private val baseURL: String) {
// (It is recommended to use @BindsInstance explained in step5 rather than the constructor argument of Module.)
@Provides
fun provideUserRepository(): UserRepository {
return UserDataRepository(baseURL)
}
}
(b). AppComponent.kt
package com.star_zero.sample.dagger_tutorial.step1.di
import com.star_zero.sample.dagger_tutorial.step1.ui.MainActivity
import dagger.Component
@Component(
modules = [
AppModule::class
]
)
interface AppComponent {
// Create a method with the class that has the field you want to inject as an argument
fun inject(activity: MainActivity)
}
Step 6: Create UI code
(a). MainViewModel.kt
package com.star_zero.sample.dagger_tutorial.step1.ui
import com.star_zero.sample.dagger_tutorial.step1.data.repository.UserRepository
import javax.inject.Inject
class MainViewModel @Inject constructor(
private val userRepository: UserRepository
) {
fun getName(): String {
return userRepository.getName()
}
}
(b). MainActivity.kt
package com.star_zero.sample.dagger_tutorial.step1.ui
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.star_zero.sample.dagger_tutorial.step1.R
import com.star_zero.sample.dagger_tutorial.step1.data.repository.UserRepository
import com.star_zero.sample.dagger_tutorial.step1.di.AppModule
import com.star_zero.sample.dagger_tutorial.step1.di.DaggerAppComponent
import timber.log.Timber
import javax.inject.Inject
class MainActivity : AppCompatActivity() {
// Field injection
@Inject
lateinit var userRepository: UserRepository
@Inject
lateinit var viewModel : MainViewModel // Since it is not an AAC ViewModel, you can create an instance normally.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Timber.d("onCreate")
val appComponent = DaggerAppComponent.builder()
.appModule ( AppModule ( " https://example.com " )) // If the Module has arguments, you need to create an instance and pass it.
.build()
appComponent.inject(this)
Timber.d("userRepository.getName = ${userRepository.getName()}")
Timber.d("viewModel.getName = ${viewModel.getName()}")
}
}