Can not Binds Dependency with parameter in contructor with Dagger and Kotlin

Viewed 31

I have some class that looks like as below: But I have an issue, I cannot provide dependency for HomeRouter. So can you guys help me solve this problem:

class HomeRouter @Inject constructor (activity: Activity) : HomeContract.Router {

    override fun finish() {
        Timber.e("Finish")
    }
}

and Module

@Module
 abstract class RouterModule {

    @Binds
     abstract fun bindHomeRouter(homeRouter: HomeRouter):HomeRouter
     
}

and in AppComponent

@Singleton
@ActivityScope
@Component(
    modules = [
        ActivityBuilder::class,
        AppModule::class,
        NetworkModule::class,
        AndroidSupportInjectionModule::class,
        FragmentModule::class,
        InteractorModule::class,
        PresenterModule::class,
        RouterModule::class
    ]
)

interface AppComponent : AndroidInjector<MyApplication> {

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: MyApplication): Builder

        fun build(): AppComponent
    }

}

The exception as below:

/src/src/viper-architecture/app/build/tmp/kapt3/stubs/debug/com/appname/di/component/AppComponent.java:13: error: [Dagger/MissingBinding] android.app.Activity cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.appname.MyApplication> {
                ^
      android.app.Activity is injected at

Thanks everyone.

1 Answers

HomeRouter requires an Activity instance, but despite its @ActivityScope annotation adjacent to @Singleton (erroneously making those two scopes appear equivalent), AppComponent only receives the MyApplication instance. There is no binding for either the general Android Activity or your specific Activity presumably named MyActivity.

Your best bet here is to follow the dagger.android guide on Injecting Activity objects, which will instruct you to either manually create a @Subcomponent or use @ContributesAndroidInjector to do so automatically. Whether you choose the subcomponent or contributing method, you'll give that your @ActivityScope and set your RouterModule to be listed in the modules={} there as well.

As a consequence, your RouterModule will not be accessible from anything in your AppComponent directly—how can it, since anything in the AppComponent can exist before any Activity instances or across several of them?—but you'll be able to @Inject a HomeRouter instance from your Activity and ensure that every Activity gets a distinct HomeRouter instance.

Related