So I adopted the steps in The way to Implement Hilt in Android App? article to transform the Android Information app to make use of Hilt Dependency Injection. The distinction in earlier article is it would not cowl the View Mannequin dependency injection.
1. Add Dependencies and @HiltAndroidApp
The preliminary setup steps are precisely the identical as the next:
2. Add @HiltViewModel
and @Inject Constructor
To ensure that Hilt to create MainViewModel
, it’s essential to annotate the category with @HiltViewModel
. @Inject constructor
can be used to inform Hilt how the dependencies may be created.
@HiltViewModel
class MainViewModel
@Inject constructor(
non-public val repository: ArticlesRepository,
) : ViewModel() {
...
}
I additionally use @Inject Constructor
on the SqlArticlesRepository
.
class SqlArticlesRepository @Inject constructor(
non-public val database: ArticlesDatabase,
non-public val webService: WebService,
) : ArticlesRepository {
...
}
3. Add @Gives
and @Binds
To create the dependencies, we use both @Gives and @Binds. @Gives
is used to create ArticlesDatabase
and WebService
cases.
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
@Gives
@Singleton
enjoyable provideDatabase(@ApplicationContext appContext: Context): ArticlesDatabase {
return Room.databaseBuilder(
appContext,
ArticlesDatabase::class.java,
"articles.db",
)
.fallbackToDestructiveMigration()
.construct()
}
}
@Module
@InstallIn(SingletonComponent::class)
object WebServiceModule {
@Gives
@Singleton
enjoyable provideWebService(): WebService {
return WebService()
}
}
@Binds
is used to create the implementation of ArticlesRepository
interface.
@Module
@InstallIn(SingletonComponent::class)
summary class RepositoryModule {
@Binds
@Singleton
summary enjoyable bindArticlesRepository(impl: SqlArticlesRepository): ArticlesRepository
}
4. Name hiltViewModel()
Composable
Now it’s executed! All guide creations beneath in MainActivity
may be eliminated.
non-public val repository by lazy {
SqlArticlesRepository(
ArticlesDatabase.getInstance(utility),
WebService(),
)
}
non-public val homeViewModel by viewModels<MainViewModel> {
MainViewModelFactory(repository)
}
[Updated – 16 Oct, 2022]: To make use of
hiltViewModel()
, it’s essential to add the next dependency.
implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'
The MainViewModel
creation may be executed by calling the hiltViewModel()
composable perform, which generates all the mandatory dependencies.
For instance, change this MainScreen
composable perform
MainScreen(homeViewModel, useSystemUIController = true)
with
MainScreen(viewModel = hiltViewModel(), useSystemUIController = true)
The database creation beneath may also be eliminated because it has been supplied by hilt @Gives
above.
companion object {
@Risky
non-public lateinit var occasion: ArticlesDatabase
enjoyable getInstance(context: Context): ArticlesDatabase {
synchronized(this) {
if (!::occasion.isInitialized) {
occasion = Room.databaseBuilder(
context.applicationContext,
ArticlesDatabase::class.java,
"articles.db")
.fallbackToDestructiveMigration()
.construct()
}
return occasion
}
}
}
This MainViewModelFactory
may also be eliminated since this has been taken care by @HiltViewModel
.
@Suppress("UNCHECKED_CAST")
class MainViewModelFactory(non-public val repository: ArticlesRepository)
: ViewModelProvider.NewInstanceFactory() {
override enjoyable <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Conclusion
All my put in Hilt modules are in SingletonComponent
scope. If I modify my put in module to a different part, for instance ViewModelComponent
or ActivityComponent
, it fails to compile, and I do not know how you can repair it. I assume that’s my subsequent step to mess around with this Hilt
.
Sure, I nonetheless do not like Hilt
. Name me grandpa, however I nonetheless desire guide dependency injection like this one: