Dagger-Hilt: An Introduction and Migrating from Dagger-Android

YASH AGARWAL
3 min readJun 16, 2020

In recent years we have seen many different dependency injections like Koin, kodein, Dagger, etc., in Android with different opinions and solutions. Among them, Dagger is the most widely used libraries for building dependency injection, but for the Dagger, the step learning curve is a bit difficult at the beginner level which is where we see developers start using frameworks such as Koin.

This is where another powerful DI named Dagger-Hilt came for the beginners and the old dagger users. We will be going to focus on how the Dagger-Hilt is different from Dagger-Android and what’s the benefits of using it.

Hilt use to set up a standard Dagger code for you which generates a set of dagger components based on your classpath that requires marking your Dagger modules with Hilt annotations to tell Hilt which component they should go into.

Since the Dagger-Hilt is in early alpha stage, so let me begin with the basics first.

Project’s gradle file

dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.28-alpha"
}

App’s build.gradle

apply plugin: 'dagger.hilt.android.plugin'//Hilt core dependencies Injection
implementation "com.google.dagger:hilt-android:2.28-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"

Start using Hilt

Hilt Application

Likewise in Dagger-Android, we use to write a component class with a builder/factory, which includes modules that we inject in the Application class after building our project.

class MyApplication : Application() {

override fun onCreate() {
super.onCreate()

val myComponent =
DaggerMyComponent
.builder()
...
.build()

myComponent.inject(this)
}
}

But in Hilt, we don’t need to create a component we just annotate the application class with @HiltAndroidApp annotation. Hilt will do everything itself. Also, the instance of an App can be injected into other modules by the Hilt. How is this possible?

@HiltAndroidApp
class MyApplication : Application() {}

Android Entry Points

In Dagger-Android, to scope and generate Subcomponent we use to use the ContributesAndroidInjector annotation which generating Subcomponent related codes automatically and removing boilerplate codes.

@Module abstract class ActivityBuilderModule { @MainScope 
@ContributesAndroidInjector(modules = [MainModule::class])
abstract fun getMainActivity(): MainActivity
}

But in Hilt, Instead of writing those annotations and ActivityModule, we use @AndroidEntryPoint annotation for enabling members injection in your other Android classes.

@AndroidEntryPoint
class MyActivity : AppCompatActivity() {
private val mainViewModel : MainViewModel by viewModels()override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate()
}
}

You can use @AndroidEntryPoint on the following types:

  1. Activity
  2. Fragment
  3. View
  4. Service
  5. BroadcastReceiver

Hilt Modules

In Dagger-Android, we use to create scope annotation to restrict the object to its component using ActivityScope, FragmentScope for managing the lifecycle of an object. But in Hilt, modules are annotated with @InstallIn which is used to initialise the corresponding component or subcomponent via @Component#modules or @Subcomponent#modules respectively. Here is an example to install a module so that anything in the application can use it, use ApplicationComponent:

@Module
@InstallIn(ApplicationComponent::class)
object AppModule {
@Provides
fun uiHelper(application: Application) = UiHelper(application)
}

And we can scope the lifecycle of objects belongs to activity components. Here is another example of Activity Scope using ActivityRetainedComponent:

@Module
@InstallIn(ActivityRetainedComponent::class)
object MainModule {
@Provides
@ActivityRetainedScoped
fun provideMenRepository(mainApi: MainApi) = MainRepository(mainApi)
}

ViewModels are not directly supported by Dagger-Hilt and to work with Dagger-Hilt in ViewModel we use Jetpack Extensions.

First, we need to set up the dependencies in Gradle for Jetpack extensions.

Let’s add the following in the app’s build.gradle like,

implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01"
kapt "androidx.hilt:hilt-compiler:1.0.0-alpha01"

In Hilt-Android, using the @ViewModelInject annotation in the ViewModel object's constructor which replaces the Dagger’s ViewModelFactory and ViewModelModule.

class MainViewModel @ViewModelInject constructor(
private val repository: MainRepository) : ViewModel() {
...
}

Why use Hilt?

  • Reduced boilerplate
  • Decoupled build dependencies
  • Simplified configuration
  • Improved testing
  • Standardized components

Sample code

Do you want to see how Hilt is used in existing apps? Go check its usage in the Application on Github

If you found this post useful, it would help others to find it if you could click on the 👏 icon below and also do follow for more articles like this — thanks!

Happy Coding :)

--

--