Search code examples
androiddagger-2dagger-hilt

Creating subcomponents with Dagger Hilt


Based on this tutorial to add subcomponents using Dagger Hilt requires

@Singleton
class UserManager @Inject constructor(
    // Since UserManager will be in charge of managing the UserComponent's
    // lifecycle, it needs to know how to create instances of it. We use the
    // provider (i.e. factory) Dagger generates for us to create instances of UserComponent.
    private val userComponentProvider: Provider<UserComponent.Builder>
) {

  /**
   *  UserComponent is specific to a logged in user. Holds an instance of
   *  UserComponent. This determines if the user is logged in or not, when the
   *  user logs in, a new Component will be created.
   *  When the user logs out, this will be null.
   */
  var userComponent: UserComponent? = null
      private set

  ...

  private fun userLoggedIn(userId: String) {
    // When the user logs in, we create a new instance of UserComponent
    val user = createUser(userId)
    userComponent = userComponentProvider.get().setUser(user).build()
  }

  private fun logout() {
    // When the user logs out, we remove the instance of UserComponent from memory
    userComponent = null
  }
}

which is how you create a subcomponent userComponent = userComponentProvider.get().setUser(user).build()

My question is how to implement Provider

private val userComponentProvider: Provider<UserComponent.Builder>

since it does not show how it's provided to UserManager class

I'm trying to create an AppComponent to test how subcomponents work with Dagger Hilt

@DefineComponent(parent = ApplicationComponent::class)
interface AppComponent {

    @DefineComponent.Builder
    interface Builder {
        fun application(@BindsInstance application: Application): Builder
        fun build(): AppComponent
    }

}

And in application

@HiltAndroidApp
class MyApplication : Application() {

    private val appComponentProvider by lazy {
        object : Provider<AppComponent.Builder> {
            override fun get(): AppComponent.Builder {
                ??????
            }

        }
    }

    val appComponent by lazy {
        appComponentProvider.get().application(this).build()
    }
    
}

How should i create builder inside get(), isn't creating anonymous class that implements Provider correct?


Solution

  • My question is how to implement Provider

    You shouldn't have to implement Provider yourself -- Dagger knows how to create a provider of any binding automatically. So in your case, you should just inject the provider into your application:

    @HiltAndroidApp
    class MyApplication: Application() {
      @Inject lateinit var provider: Provider<MySubcomponent.Builder>
    
      val mySubcomponent by lazy {
          provider.get()....build()
      }  
    }