Search code examples
androiddagger-2dagger

ContributesAndroidInjector does not inject module


I have been trying a basic implementation of dagger2 but due to some reason ContributesAndroidInjector is not injecting the defined module. I get the following error when I run my application

Error

error: [Dagger/MissingBinding] com.demo.MainPresenter cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface AppComponent {
                ^
  A binding with matching key exists in component: com.demo.di.MainActivityModule_ProvidesMainActivity.MainActivitySubcomponent
      com.demo.MainPresenter is injected at
          com.demo.MainActivity.presenter
      com.demo.MainActivity is injected at
          com.demo.di.AppComponent.inject(com.demo.MainActivity)

Below is my dagger code

@Component(modules = [
    AndroidInjectionModule::class,
    MainActivityModule::class
])
interface AppComponent {
    fun inject(application: MyApplication)

    fun inject(mainActivity: MainActivity)
}

@Module
abstract class MainActivityModule {

    @ContributesAndroidInjector(modules = [MainModule::class)
    abstract fun providesMainActivity(): MainActivity
}

@Module
class MainModule {

    @Provides
    fun providesMainPresenter(): MainPresenter {
        return MainPresenter()
    }
}

I am initialising the AppComponent in MyApplication and MainPresenter is injected in MainActivity

class MyApplication : Application(), HasActivityInjector {

    @Inject
    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

    override fun onCreate() {
        super.onCreate()
        DaggerAppComponent.create()
                .inject(this)
    }

    override fun activityInjector(): AndroidInjector<Activity> {
        return dispatchingAndroidInjector
    }

}

class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var presenter: MainPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btnLaunch.setOnClickListener { presenter.onLaunchClicked() }
    }
}

I have gone through multiple examples on the net but none of them have proved helpful. Did anyone else faced this issue?


Solution

  • You have to remove fun inject(mainActivity: MainActivity) from your AppComponent.

    While you correctly add MainModule and the presenter to the Activity Subcomponent (the @ContributesAndroidInjector stuff), your AppComponent doesn't know anything about this. You can't inject your MainActivity from there without the missing dependencies, hence the error. Please see How do I fix Dagger 2 error '… cannot be provided […]'? for some general information on your error and how you can read it.

    As a side note, you should look up Constructor Injection with Dagger to avoid writing boilerplate with modules.