0

I am new to Dagger 2. I am trying to make a simple app that has 2 activities, a login activity and a main activity, which is opened when user logs in from the login activity. I have 3 scopes @Singleton, @UserScope, and @ActivityScope. I use Subcomponents.

AppComponent.kt is the root component, and it provides UserComponent and LoginActivityComponent

@Singleton
@Component(modules=[ApplicationModule::class])
interface ApplicationComponent {
    // subcomponents
    fun plus(userModule: UserModule): UserComponent
    fun plus(loginActivityModule: LoginActivityModule): LoginActivityComponent
}

AppModule

@Module
class ApplicationModule (private val baseApp: BaseApp, private val applicationContext: Context) {

    @Provides
    @Singleton
    fun provideApplication(): Application = baseApp

    @Provides
    @Singleton
    fun provideApplicationContext(): Context = applicationContext
}

UserComponent provides MainActivityComponent

@UserScope
@Subcomponent(modules=[UserModule::class])
interface UserComponent {
    // subcomponent
    fun plus (mainActivityModule: MainActivityModule):MainActivityComponent
}

MainActivityComponent.kt

@ActivityScope
@Subcomponent(modules=[MainActivityModule::class])
interface MainActivityComponent {
    fun inject(mainActivity: MainActivity)
}

Now MainActivityModule has @Provide MainPresenter method, cause I need to inject it into MainActivity

@Module
class MainActivityModule(private val mainActivity: MainActivity) {

    @Provides
    @ActivityScope
    fun provideMainActivity(): MainActivity = mainActivity

    @Provides
    @ActivityScope
    fun provideMainPresenter(): MainPresenter = MainPresenterImpl()

}

MainActivity

class MainActivity: BaseActivity(), MainView {

@Inject
lateinit var presenter: MainPresenter

@Inject
lateinit var user: User


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setupActivityComponent()
    presenter.attachView(this)
    logoutButton.setOnClickListener {
        presenter.onLogoutButtonClicked()
    }
}

override fun setupActivityComponent() {
    BaseApp.instance.getUserComponent()?.plus(MainActivityModule(this))?.inject(this)
}

}

Yet the compiler complains: [app.di.component.MainActivityComponent.inject(app.ui.main.MainActivity)] app.ui.main.MainPresenter cannot be provided without an @Provides- or @Produces-annotated method. public abstract interface ApplicationComponent { ^ app.ui.main.MainPresenter is injected at app.ui.main.MainActivity.presenter app.ui.main.MainActivity is injected at app.di.component.MainActivityComponent.inject(mainActivity)

Harry Kane
  • 163
  • 1
  • 7
  • Please include the actual error message and relevant parts of code if you need help. Please also see here for an example and [some general information](https://stackoverflow.com/q/44912080/1837367) on your error – David Medenjak Oct 01 '19 at 19:23
  • @DavidMedenjak I have added the actual error message. I think I have included all the relevant part of code. – Harry Kane Oct 02 '19 at 00:57
  • can you please post the code where you are injecting MainPresenter ? – Manu Oct 02 '19 at 11:39
  • @Manu I just added the code where I injected MainPresenter – Harry Kane Oct 02 '19 at 15:40
  • Any particular reason why `app.getUserComponent()` is nullable? How do you intend to inject the Activity, if you first need to inject the Activity to get the class from which you get the injector? – EpicPandaForce Oct 02 '19 at 16:50
  • @EpicPandaForce userComponent is nullable because I think userComponent should be null if user has not logged in yet. Im not too sure I understand your 2nd question, but from what I understand, the MainActivity will be created. The MainActivitiyModule will be created within the MainActivity onCreate method, then the module injects the presenter into the MainActivity. – Harry Kane Oct 02 '19 at 17:37
  • `app.getUserComponent()` calls `app` which is `@Inject lateinit var` – EpicPandaForce Oct 02 '19 at 17:41
  • @EpicPandaForce the instance variable app is injected from the AppComponent, which uses ApplicationModule. I have added the ApplicationModule to the question.Sorry for any confusion – Harry Kane Oct 02 '19 at 17:50
  • When is it injected? Why would it be injected BEFORE the inject call? – EpicPandaForce Oct 02 '19 at 17:57
  • 1
    @EpicPandaForce I see your point. I have updated the code. The error still persists. It seems that the code have several issues. – Harry Kane Oct 02 '19 at 18:09

0 Answers0