Search code examples
androidkotlindaggerdagger-hilt

Android: Dagger hilt, inject navigation component


I am trying to provide my navController with dagger hilt. But the approach I am using does not work. I want to provide the navController in order to Inject it in my fragment via constructor injection.

Without Di.Module, FragmentClass

private val navController by lazy { findNavController() }
private val appBarConf by lazy { AppBarConfiguration(navController.graph) }

Current approach, Di.Module

@Module
@InstallIn(ApplicationComponent::class)
object AndroidModule {

@Provides
fun provideNavController(@ApplicationContext context: Context): NavController = lazy {
    (context as AppCompatActivity).findNavController(R.navigation.nav_main)
}.value

@Provides
fun provideAppbarConfiguration(navController: NavController): AppBarConfiguration = lazy {
    AppBarConfiguration(navController.graph)
}.value
}

I've also created the FragmentFactory class in order to inject my dependency via the constructor. I know that (context as AppCompatActivity) is the problem here, but I don't know the proper solution..

I appreciate every help, thanks!

Error

Caused by: java.lang.ClassCastException: com.example.app.App cannot be cast to androidx.appcompat.app.AppCompatActivity


Solution

  • This works for me. The activity should be provided if you install in the ActivityComponent. I'm only injecting into navigators of a Fragment. So that's why I used @InstallIn(ActivityComponent::class)

    @Module
    @InstallIn(ActivityComponent::class)
    object MainActivityModule {
    
        @Provides
        fun provideNavController(activity: Activity): NavController {
            return activity.findNavController(R.id.navHostFragment)
        }
    }
    

    The R.id.navHostFragment is in this case not the id of the navigation graph, but of the fragment host.

    Edit: as Andrew pointed out. Don’t forget to annotate your fragment with @AndroidEntryPoint