Convert View Model to Use Hilt Dependency Injection

Listed here are the steps I did and my key learnings to transform my Android Information app to make use of hilt dependency injection

This text was initially printed at vtsen.hashnode.dev on July 16, 2022.

So I adopted the steps in How to Implement Hilt in Android App? article to transform the Android News 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, you have to annotate the category with @HiltViewModel. @Inject constructor can be used to inform Hilt how the dependencies might be created.

@HiltViewModel
class MainViewModel
    @Inject constructor(
        non-public val repository: ArticlesRepository,
    ) : ViewModel() {
    ...
}
Enter fullscreen mode

Exit fullscreen mode

I additionally use @Inject Constructor on the SqlArticlesRepository.

class SqlArticlesRepository @Inject constructor(
    non-public val database: ArticlesDatabase,
    non-public val webService: WebService,
) : ArticlesRepository {
   ...
}
Enter fullscreen mode

Exit fullscreen mode



3. Add @Offers and @Binds

To create the dependencies, we use both @Provides and @Binds. @Offers is used to create ArticlesDatabase and WebService cases.

@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {

    @Offers
    @Singleton
    enjoyable provideDatabase(@ApplicationContext appContext: Context): ArticlesDatabase {

        return Room.databaseBuilder(
            appContext,
            ArticlesDatabase::class.java,
            "articles.db",
        )
            .fallbackToDestructiveMigration()
            .construct()
    }
}

@Module
@InstallIn(SingletonComponent::class)
object WebServiceModule {

    @Offers
    @Singleton
    enjoyable provideWebService(): WebService {
        return WebService()
    }
}
Enter fullscreen mode

Exit fullscreen mode

@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
}
Enter fullscreen mode

Exit fullscreen mode



4. Name hiltViewModel() Composable

Now it’s achieved! All guide creations beneath in MainActivity might be eliminated.

non-public val repository by lazy {
    SqlArticlesRepository(
        ArticlesDatabase.getInstance(software),
        WebService(),
    )
}

non-public val homeViewModel by viewModels<MainViewModel> {
    MainViewModelFactory(repository)
}
Enter fullscreen mode

Exit fullscreen mode

The MainViewModel creation might be achieved by calling the hiltViewModel() composable operate, which generates all the mandatory dependencies.

For instance, change this MainScreen composable operate

MainScreen(homeViewModel, useSystemUIController = true)
Enter fullscreen mode

Exit fullscreen mode

with

MainScreen(viewModel = hiltViewModel(), useSystemUIController = true)
Enter fullscreen mode

Exit fullscreen mode

The database creation beneath will also be eliminated because it has been offered by hilt @Offers 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
        }
    }
}
Enter fullscreen mode

Exit fullscreen mode

This MainViewModelFactory will 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")
    }
}
Enter fullscreen mode

Exit fullscreen mode



Conclusion

All my put in Hilt modules are in SingletonComponent scope. If I alter my put in module to a different element, for instance ViewModelComponent or ActivityComponent, it fails to compile, and I do not know repair it I suppose that’s my subsequent step to mess around with this Hilt.

Sure, I nonetheless don’t love Hilt. Name me grand pa, I nonetheless desire guide dependency inject like this one:



Supply Code



See Additionally

Add a Comment

Your email address will not be published. Required fields are marked *