Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Way to scope dagger subcomponents via backstack #619

Open
ursusursus opened this issue Jul 25, 2020 · 2 comments
Open

Way to scope dagger subcomponents via backstack #619

ursusursus opened this issue Jul 25, 2020 · 2 comments

Comments

@ursusursus
Copy link

Hi,
this is a uninformed question, but, often times I hear that "screen" frameworks provide a mechanism of creating and storing a subcomponent instance, and then clearing it on popping

Anybody tried something like this with Conductor?

@PaulWoitaschek
Copy link
Collaborator

I have an AddFoodController. That controller has it's own component:

@Qualifier
annotation class AddFoodLifecycle

@Subcomponent(modules = [FoodBottomBarListenerModule::class])
@AddFoodScope
interface AddFoodComponent : JustAddedComponent {

  val foodSearchComponentFactory: FoodSearchController.Component.Factory

  fun inject(target: AddFoodController)

  @Subcomponent.Factory
  interface Factory {
    fun create(
      @BindsInstance args: AddFoodArgs,
      @BindsInstance @AddFoodLifecycle lifecycle: Lifecycle
    ): AddFoodComponent
  }

  companion object {
    lateinit var factory: Factory
  }
}

This controller creates the component in its init block:

  private val component: AddFoodComponent
  init {
    component = AddFoodComponent.factory.create(args, lifecycle)
    component.inject(this)
  }

I have an FoodSearchController.

For that controller I have an interface for creating the component factory:

interface FoodSearchComponentProvider {
  val foodSearchComponentFactory: FoodSearchController.Component.Factory
}

That interface is implemented by the AddFoodController.

Now the FoodSearchController uses onContextAvailable to inject it's dependencies:

  override fun onContextAvailable(context: Context) {
    super.onContextAvailable(context)
    if (!dependenciesInjected) {
      (targetController as FoodSearchComponentProvider).foodSearchComponentFactory.create(lifecycle).inject(this)
    }
    dependenciesInjected = true
  }

That way they can share the same scoped instances. Would that work for you?

@ursusursus
Copy link
Author

ursusursus commented Jul 26, 2020

In a sense it would, youre holding the instance in one, and sharing the reference via targetController api, and when the host gets popped the component is lost.

I was thinking more of something like a purchase flow. Where none of the controllers in the logical flow instantiate the component, they just access it from "somewhere". And the instantiation would happen "automatically" else where.

I was thinking putting it in the backstackchanged listener, manually like if controller pushed is PurchaseFirstStepController then create the instance, if popped then clear it

Mortar has a way to attach stuff to backstack entry objects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants