3

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?

Prince Dholakiya
  • 3,255
  • 27
  • 43
Muhammad Ahmed AbuTalib
  • 4,080
  • 4
  • 36
  • 59

1 Answers1

1

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()) }
Carles
  • 4,509
  • 1
  • 14
  • 8