Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

findNavController with a DI tool

I have a single activity and multiple fragments styled application using the navigation component.

I am using Koin for my DI. I was wanting to create a Navigator class in my application as per the postulates of clean architecture.

This hypothetical class would look like :

class Navigator(private val navHostFragment: NavHostFragment)
{

    fun toStudentsProfile():Unit
    {
        val action = HomeFragmentDirections.toStudentsProfile()
        navHostFragment.findNavController().navigate(action)
    }

    fun toTeachersProfile():Unit
    {
        val action = HomeFragmentDirections.toTeachersProfile()
        navHostFragment.findNavController().navigate(action)
    }
}

My problem now is how should I create this under the Koin container ?

val platformModule = module {

    single { Navigator("WHAT CAN BE DONE HERE") }
    single { Session(get()) }
    single { CoroutineScope(Dispatchers.IO + Job()) }

}

Furthermore, the Koin component would get ready before the navhostfragment is ready hence it won't be able to satisfy the dependency, to begin with.

Is there a way to provide Koin with an instance of a class and then subsequently start using it?

like image 903
Muhammad Ahmed AbuTalib Avatar asked Sep 15 '25 02:09

Muhammad Ahmed AbuTalib


1 Answers

Koin allows to use parameters on injection

val platformModule = module {
    factory { (navHostFragment: NavHostFragment) -> Navigator(navHostFragment) }
    single { Session(get()) }
    single { CoroutineScope(Dispatchers.IO + Job()) }
}

I have declared the dependency as factory, i guess it could be scoped to the activity as well. Declaring it as single will lead to misbehavior, as if the activity (therefore the navhostFragment) is re-created, the Navigator object will be referencing the destroyed navhostFragment.

As the fragments will be navhostFragment children, you can obtain the Navigator object in the fragments this way:

val navigator: Navigator by inject { parametersOf(requireParentFragment()) }
like image 117
Carles Avatar answered Sep 17 '25 19:09

Carles