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