Dagger: A Dependency Injection Framework For Android
Square, a company focusing on mobile payments has recently presented a new library called Dagger, described as "A fast dependency injector for Android and Java". The source code was released in GitHub.
Dependency injection (also known as Inversion of Control) is already featured in popular frameworks such as Spring and Google Guice. However these were designed with the standard JVM in mind and not a mobile environment such as Android. While RoboGuice attempts to improve the experience of Guice on Android, Dagger takes a different approach by focusing on a simplified feature set in order to achieve better performance.
At the time of writing Dagger supports:
- Constructor injection using the standard annotation of JSR-330
- Object creation with the @Provides annotation
- A central context for the dependency tree
- Lazy injections for expensive resources
- Quantifiers for different implementations of the same interface
- Static injection (for legacy environments)
- Compile time validation of bindings
At the most basic level Dagger supports the standard Inject annotation which is also supported by Spring and Guice. In Dagger only constructor injection is supported. You cannot inject methods (the alternative way of injecting dependencies into a class). Dagger also offers a @Provides annotation that works similar to Guice.
Once the dependencies are defined, resolved classes are obtained via the ObjectGraph that holds a tree of all Dagger - initialized objects. This works in a similar way to the ApplicationContext of Spring and the Injector of Guice. Dagger also shares the concept of Modules (a collections of bindings) as found in Guice.
Some dependencies such as connection pools are expensive to produce in an eager way. Dagger supports lazy initialization of dependencies for these situations. Again the syntax is similar to Guice. For the case where multiple implementations are present for the same specification Dagger follows the @Named annotation convention.
Finally Dagger offers injection of legacy code that still uses Factories instead of dependency injection. Again this feature works in a similar manner and syntax with Google Guice.
So far it seems that Dagger supports just a subset of features found in Google Guice. This is logical considering that there is an overlap between the people responsible for each framework. However Dagger has a more minimal profile and it is clearly developed with Android in mind. The most striking missing feature is the complete lack of injection of methods and fields.
Dagger sacrifices this feature but it improves the area of error checking/detection. Usually dependency injection errors are reported during runtime when the application is already running. Dagger however includes compile time validation of annotations that will trigger compile errors for incomplete bindings. This feature could ease development of applications that are intended to run on Android.
Another big difference is the lack of scoping compared to the other popular frameworks. Dagger supports only the @Singleton annotation and nothing else. Again this is to be expected since Android development has different needs than standard Web development (which comes with request and session scopes).
It is also worth noting that Spring users have not only noticed Dagger, but also created two issue reports as shortcomings of Spring compared to Dagger. The first has to do with the fact that Spring only injects classes that have an annotation on their own and the second is the inability of Spring to differentiate classes that implement an interface with generics.
At the moment the only documentation available on Dagger is the README file. The code is open source under the Apache 2 Licence. Notice also that the project has not made an official release (there isn't even a source code tag) so you might want to take this into account when evaluating Dagger for production deployments.
Typo in the feature list
Mike Amundsen May 29, 2015
Ben Linders May 28, 2015