@Inject
annotation
1. On constructor
Automatically obtains an instance of parameters and invokes the constructor.
2. On field
“If your class has @Inject
-annotated fields but no @Inject
-annotated constructor, Dagger will inject those fields if requested, but will not create new instances. Add a no-argument constructor with the @Inject
annotation to indicate that Dagger may create instances as well.” - Link
@Provides
annotation
Inject annotation will call the injected constructor to initialize the object. @Provides
annotation enables customizable method to “provide” injected object.
@Provides static Heater provideHeater() {
return new ElectricHeater();
}
Whenever object Heater is requested, this provideHeader() will be called.
To create an alias of a type:
@Provides static Heater provideHeater(ElectricHeater heater) {
return heater;
}
@Binds
annotation
@Binds Heater bindHeater(ElectricHeater impl);
Can also create an alias of one type.
@Module
annotation
All @Binds
and @Provides
are required to be put in a @Module
annotated interface.
@Module
interface HeaterModule {
@Binds Heater bindHeater(ElectricHeater impl);
}
@Component
annotation
This annotation is used at Application level. By annotating an interface with @Component
with defined modules, Dagger framework will create a concrete class named as “DaggerXXX” with builder().
@Component(modules = DripCoffeeModule.class)
interface CoffeeShop {
CoffeeMaker maker();
}
CoffeeShop coffeeShop = DaggerCoffeeShop.builder()
.dripCoffeeModule(new DripCoffeeModule())
.build();
@Singleton
annotation
Can be used to annotate injectable classes or providers.
@Reusable
annotation
“That means that if you install a module with a @Reusable binding in a component, but only a subcomponent actually uses the binding, then only that subcomponent will cache the binding's object. If two subcomponents that do not share an ancestor each use the binding, each of them will cache its own object. If a component's ancestor has already cached the object, the subcomponent will reuse it.” – Link
Lazy wrapper
@Inject
or @Provides
annotated type can be wrapped in Lazy defers instantiation until the first call to get()
method.
class GrindingCoffeeMaker {
@Inject Lazy<Grinder> lazyGrinder;
public void brew() {
while (needsGrinding()) {
// Grinder created once on first call to .get() and cached.
lazyGrinder.get().grind();
}
}
}
Provider wrapper
A Provider
class BigCoffeeMaker {
@Inject Provider<Filter> filterProvider;
public void brew(int numberOfPots) {
...
for (int p = 0; p < numberOfPots; p++) {
maker.addFilter(filterProvider.get()); //new filter every time.
maker.addCoffee(...);
maker.percolate();
...
}
}
}
@Qualifier
annotation
Can be used when object initialization cannot be determined only by its type. In Spring, @Name
is used for “name” based wiring. In Dagger, you can annotate an annotation interface with @Qualifer
to define your own wiring annotation.
@Qualifier
@Documented
@Retention(RUNTIME)
public @interface Named {
String value() default "";
}
class ExpensiveCoffeeMaker {
@Inject @Named("water") Heater waterHeater;
@Inject @Named("hot plate") Heater hotPlateHeater;
...
}
@Provides @Named("hot plate") static Heater provideHotPlateHeater() {
return new ElectricHeater(70);
}
@Provides @Named("water") static Heater provideWaterHeater() {
return new ElectricHeater(93);
}
@BindsOptionalOf
annotation
@BindsOptionalOf abstract CoffeeCozy optionalCozy();
That means that @Inject constructors and members and @Provides methods can depend on an Optional
@BindsInstance
annotation
Marks a method on a component builder or a parameter on a component factory as binding an instance to some key within the component.
@Component(modules = AppModule.class)
interface AppComponent {
App app();
@Component.Builder
interface Builder {
@BindsInstance Builder userName(@UserName String userName);
AppComponent build();
}
}
public static void main(String[] args) {
if (args.length > 1) { exit(1); }
App app = DaggerAppComponent
.builder()
.userName(args[0])
.build()
.app();
app.run();
}