I've looked at a couple different articles which seem to suggest two different ways of doing custom scoping in Dagger 2:
MVP Presenters that Survive Configuration Changes Part-2 (Github repo):
@Hello1Scope
and @Hello2Scope
for Hello1Fragment
and Hello2Fragment
respectivelyTasting Dagger 2 on Android:
@PerFragment
.From what I understand, it seems that, as in method 2, it should be okay to have a single scope defined that can be used for all fragments (i.e., @PerFragment
). In fact (please correct me if I'm wrong), it seems like the name of the custom scope is irrelevant, and it's only where the subcomponent is created (i.e. in Application, Activity, or Fragment) that matters.
Is there any use case for defining a unique scope for each fragment such as in case 1?
Dagger 2 provides @Scope as a mechanism to handle scoping. Scoping allows you to “preserve” the object instance and provide it as a “local singleton” for the duration of the scoped component. In the last tutorial, we discussed a special scope called @Singleton.
It's officially deprecated and you can pretty much ignore it. Google's framework, which became dominant in Android ecosystem, was originally called Dagger 2. Sometimes we still refer to it as such, but, in most cases, we simply call it Dagger today.
Annotation Type ContributesAndroidInjectorThe injector is implemented with a Subcomponent and will be a child of the Module 's component. This annotation must be applied to an abstract method in a Module that returns a concrete Android framework type (e.g. FooActivity , BarFragment , MyService , etc).
After reading the answer by @vaughandroid, and What determines the lifecycle of a component (object graph) in Dagger 2? I think I understand custom scopes well enough to answer my own question.
First, here are a couple rules when dealing with components, modules, and scoping annotations in dagger2.
@Singleton
or @CustomScope
).@Singleton
for the root Component (and it's modules) only. Subcomponents must use a custom scope, but the functionality of that scope is exactly the same as @Singleton
.Now, to answer the question: I would say create a new named scope for each conceptually different scope. For example, create a @PerActivity
, @PerFragment
, or @PerView
annotation that indicates where the component should be instantiated, and thus indicating its lifetime.
Note: this is a compromise between two extremes. Consider the case of a root component and n subcomponents you will need:
@Singleton
and @SubSingleton
), and@Singleton
, @SubSingleton1
, ... @SubSingletonN
). Application:
/** AppComponent.java **/ @Singleton @Component( modules = AppModule.class ) public interface AppComponent{ void inject(MainActivity mainActivity); } /** AppModule.java **/ @Module public class AppModule{ private App app; public AppModule(App app){ this.app = app; } // For singleton objects, annotate with same scope as component, i.e. @Singleton @Provides @Singleton public App provideApp() { return app; } @Provides @Singleton public EventBus provideBus() { return EventBus.getDefault(); } }
Fragment:
/** Fragment1Component.java **/ @PerFragment @Component( modules = {Fragment1Module.class}, dependencies = {AppComponent.class} ) public interface Fragment1Component { void inject(Fragment1 fragment1); } /** Fragment1Module.java **/ @Module public class Fragment1Module { // For singleton objects, annotate with same scope as component, i.e. @PerFragment @Provides @PerFragment public Fragment1Presenter providePresenter(){ return new Fragment1Presenter(); } } /** PerFragment.java **/ @Scope @Retention(RetentionPolicy.RUNTIME) public @interface PerFragment {}
Your understanding is correct. The named scopes allow you to communicate intention, but they all work the same way.
The lifetime of the Component instance is important though. 2 different instances of the same component will provide different object instances, even scoped ones.
Scope names should indicate the lifetime of the provided object (which matches that of the Component instance) so @PerFragment
makes much more sense to me.
From a quick look at the "MVP Presenters..." tutorial, it's not clear to me exactly what the author's intention is with having separate scopes. Since the names are just throwaway ones, I wouldn't read too much into it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With