Peike
Peike

Reputation: 727

How to create custom scope and share same instances using Dagger Android

So here are the things I know from the doc

  1. Dagger Android under the hood is creating subcomponent for each Activity annotated with ContributesAndroidInjector
  2. You can apply custom scope to the method where ContributesAndroidInjector is annotated to
  3. If two sibling subcomponents have the same scope, they will still have different scope instances
  4. If an Activity is in a subcomponent, it can have its own subcomponent which can contain Fragments. Those Fragments will share the scoped instances the Activity has.

Now my question is: How to have one Activity be a subcomponent of another activity using Dagger Android?

I want to do this because I want to achieve things like @UserScope/@SessionScope.

From this I know that I can do it with just Dagger not Dagger Android. But with Dagger Android, you can only have the Application (which is the AndroidInjector) to inject Activity. You can not have an Activity used as a holder or host of the parent subcomponent to inject another Activity.

Am I understanding it correctly?

05/14/2018 Update:

I ended up getting rid of Dagger Android. So no more ContributesAndroidInjector, just pure Dagger. And to inject Activity/Fragment, I use the way that's recommended here. It will be something like this:

class MyActivity : AppCompatActivity() {
    private val factory: ViewModelProvider.Factory = Injector.myCustomScope().factory()
}

And we are trying to make sure the factory is the only thing that Activity/Fragment needs.

So far it's been great.

Upvotes: 4

Views: 1070

Answers (2)

CROSP
CROSP

Reputation: 4617

You can create a custom Scope called for example @PerScreen, also you will have @PerActvity scope. The difference between these scopes is that the @PerActivity scope will maintain shared dependencies between all activities like Context, Layout Inflater, etc. And all activity specific dependencies will be scoped as @PerScreen.

@PerApplication -> @PerActivity -> @PerScreen

This could structured like that. I have explained scopes under the hood in my blog post, you can refer to it to get better understanding of this matter.

Upvotes: 1

David Medenjak
David Medenjak

Reputation: 34532

How to have one Activity be a subcomponent of another activity using Dagger Android?

tl;dr You can't. Dagger Android follows a strict AppComponent > ActivityComponent > FragmentComponent scheme and there is no way to add custom scopes in-between.


I suggest you have a look at the Dagger Android source code, it's really not that much. It's basicalle a HashMap for each layer where you look up the component builder and build the subcomponent. A fragment looks at its parent Activity, an Activity looks at the Application. There is no feature where you can add custom components between layers.

What you can do is create your own variant of "Dagger Android" where you can implement your own interfaces and mix/match components as you need them. But that's quite a bit of extra work. I created a @PerScreen scope that survives configuration changes as a proof of concept if you are interested to see how you could do such a thing.

Upvotes: 3

Related Questions