Guowei Lv

1 minute read

Let’s create a ScreensNavigator interface:

interface ScreensNavigator {
    fun navigateBack()
    fun toQuestionDetails(questionId: String)

And ScreensNavigatorImpl implements it:

class ScreensNavigatorImpl @Inject constructor(private val activity: AppCompatActivity) :
    ScreensNavigator {

    override fun navigateBack() {

    override fun toQuestionDetails(questionId: String) {
        QuestionDetailsActivity.start(activity, questionId)

Now we have a problem that in activities and fragments we want to inject the interface type:

lateinit var screensNavigator: ScreensNavigator

But Dagger only knows how to create ScreensNavigatorImpl. How can we help Dagger to figure out when we want an ScreensNavigator, we need an instance of ScreensNavigatorImpl? The trick is to use @Binds.

abstract class ActivityModule {

    abstract fun screensNavigator(screensNavigatorImpl: ScreensNavigatorImpl): ScreensNavigator

     * Moved these to companion object because otherwise we get this error
     * A @Module may not contain both non-static and abstract binding method
    companion object {
        fun layoutInflater(activity: AppCompatActivity): LayoutInflater =

        fun fragmentManager(activity: AppCompatActivity) = activity.supportFragmentManager

Now that we have to make ActivityModule an abstract class, we need to remove fun activityModule() from ActivityComponent.Builder. And Dagger knows how to construct abstract Modules by itself.

comments powered by Disqus