# 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)
}
```