Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why scope annotations have RUNTIME retention in Dagger 2?

Tags:

dagger-2

Dagger 2 has compile-time validation, so why do the scope annotations have RUNTIME retention? Why are they needed at runtime?

like image 448
netimen Avatar asked Mar 31 '16 10:03

netimen


People also ask

How does the custom scope work in Dagger?

A scope is an annotations class with specific additional annotations: @Scope and @Retention. @Scope annotation is provided by Dagger library to define custom scopes. In our example, we create two scopes: @ActivityScope (for activities) and @FragmentScope (for fragments).

What are scopes in Dagger 2?

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.

Which annotation is not used in Dagger?

Dagger cannot instantiate or inject classes that do not have neither @Inject nor @Provides annotations. In order to get an instance of the root object (CoffeeMaker), we need to create an interface that has a function that returns any class of the graph that we want. This interface must have the @Component annotation.

What is subcomponent in Dagger?

In Dagger 2, component is the main container-like object that binds all the dependencies (or it's factory). Subcomponent are components that is like an extension to its parent component. It can be used for. Partition the dependencies into different compartments.


1 Answers

Though I don't know for sure, I'd guess that Scopes necessarily have runtime retention because JSR 330's @Scope requires scopes to have runtime retention. (@Qualifier has the same restriction.) Both Dagger 1 and Dagger 2 advertise JSR-330 compatibility, and (as David mentions in the comments) there are plenty of runtime dependency injection solutions that would absolutely require runtime-retained scope annotations.

For Dagger in particular, I can't imagine why they'd actually be read at runtime either, though I suppose some external libraries could make use of the annotation.


Edit from comments + Android multidex caveat

This is not necessarily a problem, legacy or otherwise: Many DI systems configure at runtime and require the annotation. Dagger is notable in that it doesn't, but the spec was not written in a way that allows for runtime retention to be optional. This frees app developers to replace Dagger with a different JSR330 framework like Guice or Spring, and it frees library developers to make DI-compatible tools or frameworks agnostic to whether they are compile-time-configured or runtime-configured. That spec clarity (i.e. without implementation options) and flexibility (compile time or runtime) seems worth the cost of unnecessary annotation retention and the cost of learning.

However, this can be a problem in large Android apps because Android keeps runtime-annotated classes in the main dex by default; older versions of Android fail to load runtime annotations if the annotated class is in a secondary dex. See this bug linked from the keepRuntimeAnnotatedClasses docs for details. Though you could consider this a Dagger problem because of Dagger's applicability to large Android apps, it's more of a bug with Android annotation handling, for which Dagger would need to diverge from the JSR-330 spec in order to handle itself.

like image 92
Jeff Bowman Avatar answered Oct 19 '22 01:10

Jeff Bowman