How can I return a component from Application to module?

258 views Asked by At

Trying to understand the following example and do something similar.

In my application there is a module, in which I want to use Dagger. To do this I need an Application class in which I initialize and store AppComponent

Judging from the documentation I need to create an interface with a component from my module:

interface PasscodeSetupComponentProvider {
    fun providePasscodeSetupComponent(): PasscodeComponent
}

Then I will implement this interface for my Application class:

open class FenturyApplication : PasscodeSetupComponentProvider {

    lateinit var appComponent: AppComponent

    override fun onCreate() {
        super.onCreate()
        appComponent = DaggerAppComponent.builder()
            .appModule(AppModule(applicationContext))
            .build()
    }

    override fun providePasscodeSetupComponent(): PasscodeComponent {
        return appComponent.passcodeComponent
    }
}

But judging by the example from the documentation I don't understand what should be in my interface Appcomponent namely passcodeComponent.

In the example, it looks like this:

class MyApplication: Application(), LoginComponentProvider {
  // Reference to the application graph that is used across the whole app
  val appComponent = DaggerApplicationComponent.create()

  override fun provideLoginComponent(): LoginComponent {
    return appComponent.loginComponent().create()
  }
}

I added the following code to my AppComponent:

@Component(modules = [AppModule::class])
@Singleton
interface AppComponent {
    val applicationContext: Context
    fun passcodeComponent(): PasscodeComponent
}

And if I understood correctly, then in the fragment that is in my module, I can write the following:

lateinit var passcodeComponent: PasscodeComponent

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val context = activity?.applicationContext ?: return
    passcodeComponent = (context as PasscodeSetupComponentProvider).providePasscodeSetupComponent()
    passcodeComponent.inject(this)

After that I hope I can use dagger in my module.

1

There are 1 answers

0
Ahmed I. Khalil On

You're missing a crucial part of how AppComponent is written. You can read the complete code in this link.

Please note how Google is declaring the LoginComponent (as Subcomponent) and how do they declare it inside AppComponent in order do return a new instance of LoginComponent.

AppComponent (copied from the link I posted)

@Singleton
@Component(modules = [NetworkModule::class, SubcomponentsModule::class])
interface ApplicationComponent {
// This function exposes the LoginComponent Factory out of the graph so consumers
// can use it to obtain new instances of LoginComponent
fun loginComponent(): LoginComponent.Factory
}

And the code for LoginComponent

@Subcomponent
interface LoginComponent {

    // Factory that is used to create instances of this subcomponent
    @Subcomponent.Factory
    interface Factory {
        fun create(): LoginComponent
    }

    fun inject(loginActivity: LoginActivity)
}