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.