Skip to content Skip to sidebar Skip to footer

Dagger2 What Is The Purpose Of Adding A Scope Tag To Components?

I've created a component and it only last for the lifetime of the activity. I did not use any scope annotations and only quick example of the life time of the component looks like

Solution 1:

By using scopes on component and scopes on module provider method, you can ask Dagger2 to create scoped providers for you.

In order to get a scoped provider in your module's provider method, you must put the scope on the component as well.

You can specify only one scope on a given component, and in a scoped component, you can only have modules with that scope on its provider methods, or the provider methods can also be unscoped.

Unscoped providers give you a new instance on every inject call. Scoped providers store a single instance for every inject call to that specific component instance.

@Component(modules={HelloModule.class})@SingletonpublicinterfaceHelloComponent {
    Hello hello();
    World world();

    voidinject(MainActivity mainActivity);
}

@ModulepublicclassHelloModule {
    @Providespublic Hello hello() { returnnewHello(); } //new instance each call to inject@Provides@Singletonpublic World world() { returnnewWorld(); } //one instance per component
}

It is also worth noting that if you subscope another component to inherit its dependencies (using subcomponent or component dependency), you can only depend on one other scoped component. Think of it like how "multiple inheritance" is not allowed in Java, you also cannot depend on multiple scoped components and inherit their dependencies, only one.

Typically you have a singleton scope, and you subscope your components according to the top-level separation of modules in your application.

@Component(modules={ApplicationModule.class})@SingletonpublicinterfaceApplicationComponent {
    Something something();
}

@Component(dependencies={ApplicationComponent.class}, modules={MainActivityModule.class})@ActivityScope//this is a subscoped component that inherits from ApplicationComponentpublicinterfaceMainActivityComponentextendsApplicationComponent {
    OtherThing otherThing();

    voidinject(MainActivity mainActivity);
}

According to Martin Fowler, the right way to slice your application into pieces on the top-level is by features, such as GalleryComponent, SettingsComponent, etc. and not by layers (data, domain, presentation).

Solution 2:

Scopes manage the instance creation across multiple requests for the same type. Imagine if you had this:

@Inject
AlmondButter someAlmondButter;
@Inject
AlmondButter otherAlmondButter;

This would create two separate AlmondButter instances. A trivial case, but hopefully it illustrates the point that each time you request the dependency, a new one is created.

Imagine now you have two different classes, each with a field @Inject AlmondButter sharedAlmondButter. If you want them to have the same exact instance, a scope will handle that for you.

Similarly, with any dependency you have, you can inject a Provider<T>, i.e. @Inject Provider<AlmondButter> almondButterProvider. This can allow you to call almondButterProvider.get() to retrieve a new instance. If you then wanted all values returned by .get() to be the same instance, a scope would accomplish the same thing.

Post a Comment for "Dagger2 What Is The Purpose Of Adding A Scope Tag To Components?"