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 that there is @Scope
annotated Dagger Component above. The effect of the @SomeScope
is that: for the lifetime of the SomeComponent
, there will be one and only one SomeObject
instance exists. In other words, @SomeScope
can be used to "instruct" the 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" when requested. If we throw out the code related to being thread-safe, it will look 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 the scoped injection.
In Android, a @ActivityScope
declared as:
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {}
Is often used to ensure that the scoped annotation object is singleton within the lifecycle of the Activity
given that, there is only one DaggerComponent
associated to that Activity
.