Let the Dependency Injection work for you
Recently I received a comment on a code review pointing on this line in one of my ViewModels:
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
My colleague suggested refactoring it, that the Dependency Injection framework should provide the proper system service for me.
Examples
I’m using Koin and Dagger + Hilt, so I’ll provide a few examples using these frameworks.
Dagger + Hilt
Providing
@Module
@InstallIn(SingletonComponent::class)
object AndroidServiceModule {
@Provides
@Singleton
fun provideDownloadManager(context: Context) = context.getSystemService<DownloadManager>()!!
}
Usage
@HiltViewModel
class SomeViewModel
@Inject internal constructor(private val downloadManager: DownloadManager) {
fun downloadRequest(request: DownloadManager.Request) {
downloadManager.enque(request)
}
}
Koin
Providing
val androidServiceModule = module {
single { androidContext().getSystemService(Context.INPUT_METHOD_SERVICE)!! as InputMethodManager }
}
Usage
class SomeFragment {
private val inputMethodManager: InputMethodManager by inject()
override fun onResume() {
super.onResume()
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
}
}
Conclusion
This way I could eliminate one more context
dependency in ViewModels, for example. In addition, the code is a lot cleaner, you don’t have to read long getWhateverService()
calls.