Dagger 2 is a dependency injection library that relies heavily on annotation preprocessing to automatically generate a series of classes that provide dependencies to various parts of your application. The preprocessing occurs as part of compilation. The class files that are created are human readable — some are meant to be referenced just like any other java classes, others should just silently do their magic in the background.
Dagger 2 uses the following annotations:
- @Module and @Provides: define classes and methods which provide dependencies
- @Component: enable selected modules and used for performing dependency injection
- @Inject: request dependencies. Can be used on a constructor, a field, or a method
Module and Providers
Get your bean ready with @Provides annotation on method level and remember to put @Module at each class that containing them. Any parameter given in method with @Provides will be injected as long as the parameter already created before as bean.
[pastacode lang=”java” user=”Felixsu” path_id=”54Aqo” file=”dagger2_module.java” highlight=”” lines=”” provider=”bitbucketsnippets”/]
Module also become a building block for each component. Everything provided by modules that component depends on, would able to be injected as in provideSharedPreference
method.
Inside module, we can define scope of a providers with extra annotation like @Singleton and/or create any self made custom one. Those scope would be useful later in component section. Please take a note, @Singleton is not provided by Dagger, it only a conventions for us to flag providers that supposed to created once in Application lifecycle, so feel free to use any annotation if you want.
Component
Responsible to inject any fields and constructors that annotated with @Inject. Component defines the connection between provider of objects (modules) and the objects which expresses a dependency. Component also need to be annotated with scope and it will only takes bean coming from providers annotated with same scope.
[pastacode lang=”java” user=”Felixsu” path_id=”54Aqo” file=”dagger2_component.java” highlight=”” lines=”” provider=”bitbucketsnippets”/]
Later component can become beans provider for other component. Let say you have Singleton SharedPrefereces in AppModule and want to use it on your MainActivityComponent, then you need MainActivityComponent depends on AppComponent and explicitly provides method which exposed the singleton SharedPreferences bean.
[pastacode lang=”java” user=”Felixsu” path_id=”54Aqo” file=”dagger2_component_activity.java” highlight=”” lines=”” provider=”bitbucketsnippets”/]
Target
Last part of this post, targeting instance that would be injected by our beans. To Inject the beans, simply put @Inject annotation whether in fields, constructor, or even method*.
[pastacode lang=”java” user=”Felixsu” path_id=”54Aqo” file=”dagger2_injections_activity.java” highlight=”” lines=”” provider=”bitbucketsnippets”/]
Component interface we built before will be implemented by Dagger 2 for our use. Dagger 2 will create us a component builder that get ready all necessary bean inside its component object. Any method that doesn’t have qualified parameter, like void inject(MainActivity activity), will be used to inject the parameter itself. So when we call inject(this) in snippet above, it means Dagger 2 would inject all @inject annotated things with provided beans.
*for method parameter injections i haven’t tried it myself
Additional read:
- http://www.vogella.com/tutorials/Dagger/article.html#introduction-to-the-concept-of-dependency-injection
- http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/
Working sample codes:
Leave a Reply