Android – Dagger2 – Basic

In previous entry, I explained introduction of Dagger2 in Android (Android – DI – Dagger).

In this time, from Google Document (Using Dagger in Android apps), explain more details of Dagger2.

Component and Module

Component and Module is main part of DI.

  • Component : Bridge between Activity, Fragment and Module. 1 Activity 1 Component is basic
  • Module : Functions, covered one function.


Components, and Application class


Main Component. It contains Subcomponent and modules (Submodule as modules, and create Factory)

@Component(modules=[NetworkModule::class, DataSubComponentModule::class])
interface ApplicationComponent {

    // Main Component injection
  //  fun inject(activity: MainActivity)

    fun dataComponent() : DataSubComponent.Factory


interface DataSubComponent {

    // Factory that is used to create instances of this subcomponent
    interface Factory {
        fun create(): DataSubComponent

    // This tells Dagger that MainActivity requests injection from LoginComponent
    // so that this subcomponent graph needs to satisfy all the dependencies of the
    // fields that MainActivity is injecting
    fun inject(activity: MainActivity)

    // Other injection fragment etc...
    fun inject(fragment: DataFragment)

Add inject codes (All Activity and Fragment to use this component), Prepare Factory to access from ApplicationComponent



@Module(subcomponents = [DataSubComponent::class])
class DataSubComponentModule {}


class NetworkModule {

    // @Provides tell Dagger how to create instances of the type that this function
    // returns (i.e. DataRetrofitService).
    // Function parameters are the dependencies of this type.
    fun provideDataRetrofitService() : DataRetrofitService {
        return Retrofit.Builder()

    fun provideDataRetrofitService(okHttpClient: OkHttpClient) : DataRetrofitService {
        return Retrofit.Builder()

Provides Service code to call them from Component.

Model and ViewModel


data class Data(val name: String)

This is just data. Data from Retrofit response.


class DataViewModel @Inject constructor(
    private val dataRepository: DataRepository

ViewModel (of MVVM). Manage data and communicate with Model and View (Activity, Fragment) This can be test in JUnit general Test



// Definition of a custom scope called ActivityScope
@Retention(value = AnnotationRetention.RUNTIME)
annotation class ActivityScope

Repository and Service


class DataRepository @Inject constructor(
    private val localDataSource: DataLocalDataSource,
    private val remoteDataSource: DataRemoteDataSource
) {

class DataLocalDataSource @Inject constructor() {}

class DataRemoteDataSource @Inject constructor(private val dataService: DataRetrofitService) {}

Repository is data manipulation codes


interface DataRetrofitService {
    fun getData() : Call<Data>

This is Retrofit Service codes, define API request and response

Activity and Fragment


class DataFragment : Fragment() {

    @Inject lateinit var dataViewModel: DataViewModel

    override fun onAttach(context: Context) {

        (activity as MainActivity).dataSubComponent.inject(this)

        // Now you can access dataViewModel here and onCreateView too
        // (shared instance with the Activity and the other Fragment)

Have One ViewModel, and Get component from activity. And inject


class MainActivity : AppCompatActivity() {

    // You want Dagger to provide an instance of LoginViewModel from the graph
    // Field injection should only be used in Android framework classes where constructor injection cannot be used.
    lateinit var dataViewModel : DataViewModel

    // Reference to data graph
    lateinit var dataSubComponent: DataSubComponent

    // Activity -> ViewModel -> Repository -> DataSource -> Retrofit

    override fun onCreate(savedInstanceState: Bundle?) {
        // Make Dagger instantiate @Inject fields in this activity

        // Main Component injection
        //(applicationContext as MyApplication).appComponent.inject(this)
        // dataViewModel is available

        // Subcomponent injection
        dataSubComponent = (applicationContext as MyApplication).appComponent.dataComponent().create()
        // dataViewModel is available


Have one ViewModel, and have Component from Application


class MyApplication : Application() {

    val appComponent = DaggerApplicationComponent.create()

Register ApplicationComponent using Dagger.


Let’ try ViewModel test (no concrete implementation)

ViewModel test is simple JUnit test. In Android, there are 2 types of test by default

  • androidTest
  • test

We do test for ViewModel in test.


testImplementation 'org.mockito:mockito-core:3.3.3'
testImplementation 'android.arch.core:core-testing:1.1.1'

testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

This is test dependency. Use mockito for API mock.


class DataViewModelTest {

    var instantExecutorRule = InstantTaskExecutorRule()

    private lateinit var repository: DataRepository
    private lateinit var viewModel: DataViewModel

    fun setUp() {
        repository = mock(
        viewModel = DataViewModel(repository)

    fun testDataViewMode() {

Use InstantTaskExecutorRule to use code as synchronous.

ViewModel is defined in @Before. API is covered by Mock object.

Professional Programmer2