---
# System prepended metadata

title: Dagger2
tags: [Android, Dagger2, Dependency Injection]

---

# Dagger2
###### tags: `Dependency Injection` `Dagger2` `Android`
[TOC]
# Introduction: Base Concepts
## @Inject
Tells which variable to Inject
## @Module
How to create the object to Inject
## @Component
Tells us what modules are used, and link them to places that they are injected

# Implementation
## 1. Create the module to specify how the objects to be injected are created
To specify the **module**, we need the **@Module** annotation at the beginning. 
Furthermore, for all the ways(Methods) to inject those objects, we have to provide **@Provides** annotation and the method has to provide the object to be injected.
```kotlin=
@Module
class ApiModule {
    private val BASE_URL = "https://raw.githubusercontent.com"

    @Provides
    fun provideCountryApi() : CountriesApi {
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
            .create(CountriesApi::class.java)
    }
    
    @Provides
    fun provideCountryService() : CountryService {
        return CountryService()
    }
}
```

## 2. State what variables to be injected 
In this case, variables to be injected should be set as **lateinit var** because they will be instance automatically later.

### How are they injected?
After stating the variable as lateinit var, you have to put:
```kotlin=
init {
    ComponentName.create().injectionFunctionName(varPassed)
}
```

Example:
**Note:** DaggerApiComponent will be available after creating the component and rebuilding the project.
```kotlin=
class CountryService {
    @Inject
    lateinit var api : CountriesApi

    init {
        DaggerApiComponent.create().inject(this)
    }

    fun getCountries() : Single<ArrayList<Country>>{
        return api.getCountries()
    }
}
```

## 3. Create the link by creating the component
Only the component will know which Modules are available, in this case **ApiModule.kt**
By providing different methods, we can tell from which class/place they are being injected by seeing the parameter.
```kotlin=
@Component(modules = [ApiModule::class])
interface ApiComponent {
    fun inject(service: CountryService)

    fun inject(viewModel: ListViewModel)
}
```