About Dagger 2 Scope Injection
What Does @Scope Do?
If a scope annotation is present, the injector may retain the instance for possible reuse in a later injection.
@SomeScope
@Component(dependencies = SomeModule.class)
interface SomeComponent {}
@Module
class SomeModule {
@SomeScope
SomeObject createObject();
}
Given the @Scope-annotated Dagger component above, the effect of @SomeScope is that, for the lifetime of SomeComponent, there will be one and only one SomeObject instance.
In other words, @SomeScope can be used to instruct SomeComponent to keep the SomeObject for later use.
How Is @Scope Implemented?
Under the hood, the DoubleCheck class is used internally to keep the object reference and re-inject it when requested.
If we remove the thread-safety-related code, it looks like this:
public final class DoubleCheck<T> {
private static final Object UNINITIALIZED = new Object();
private volatile Provider<T> provider;
private volatile Object instance = UNINITIALIZED;
@Override
public T get() {
if (instance == UNINITIALIZED) {
instance = provider.get();
}
return (T) instance;
}
}
From the code above, multiple calls to DoubleCheck.get() will return the same instance, which serves the purpose of scoped injection.
Android Example
In Android, an @ActivityScope declared as follows is often used to ensure that the scoped object is a singleton within the lifecycle of the activity, given that there is only one Dagger component associated with that activity.
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {}