Dagger by Square
Dependency Injection for Android
Laurynas Veržukauskas
@im0rtality
2014
DAGger
- Directed
- Acyclic
-
Graph
DEPENDENCY INJECTION
- Decoupling
-
Uniformity
WHY?
- Works on Android!
- Fast
- Dagger - generates code up-front,
- Guice - uses Reflection
- Optional compiler plugin can flag various errors at compile time:
- Detect cyclic dependencies
- Detect unused and duplicate bindings
- Detect incomplete modules
- Simple (but limited) API compared to Guice
-
Uses standard annotations where possible (javax.inject.*)
USING DAGGER 1/3
dependencies {compile 'com.squareup.dagger:dagger:1.2.1' ... }
USING DAGGER 2/3
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
...
}
@Module
class DripCoffeeModule {
@Provides Heater provideHeater() {
return new ElectricHeater();
}
}
USING DAGGER 3/3
public static void main(String[] args) { ObjectGraph og = ObjectGraph.create(new DripCoffeeModule());// og.plus(new AnotherCoffeeModule); CoffeeApp coffeeApp = og.get(CoffeeApp.class);coffeeApp.brew(); }
@Singleton
Single instance of the value for all of its clients
@Provides @Singleton Heater provideHeater() {
return new ElectricHeater();
} @Singleton
class CoffeeMaker {
...
}
Provider<T>
Provider<T> creates a new instance of T each time .get() is called
class BigCoffeeMaker { @Inject Provider<Filter>filterProvider; public void brew(int numberOfPots) { ... for (int p = 0; p < numberOfPots; p++) { //new filter every time. maker.addFilter(filterProvider.get()); maker.addCoffee(...); ... } } }
@Named("foo")
class ExpensiveCoffeeMaker {
@Inject @Named("water") Heater waterHeater;
@Inject @Named("hot plate") Heater hotPlateHeater;
...
}
@Provides @Named("hot plate") Heater provideHotPlateHeater() {
return new ElectricHeater(70);
}
@Provides @Named("water") Heater provideWaterHeater() {
return new ElectricHeater(93);
}
Lazy<T>
class GridingCoffeeMaker { @Inject Lazy<Grinder>lazyGrinder; public void brew() { while (needsGrinding()) { // Grinder created once on first call to .get() and cached. lazyGrinder.get().grind(); } } }
@Inject @Singleton Lazy<Foo> foo; // ??? COMPILE-TIME CHECKING
[ERROR]: Graph validation failed: You have these unused @Provider methods:
1. coffee.DripCoffeeModule.provideChiller()
-
Checks your dependencies
- Generates DI classes for debugging
- Generates DI graph representation (Graphviz)
WHERE IT FALLS SHORT
-
Injectable objects MUST have @Inject constructor
-
Can't inject constructors that throw exceptions
- Can't inject methods
- Some boilerplate code
CONCLUSION
-
awesome
- detecting dependency problems at compile time
- simple api
-
not so much
- noticeable performance only on older devices
- some quirks
QUESTIONS?
https://github.com/square/dagger
Dagger
By Laurynas Veržukauskas
Dagger
Dependency Injection for Android
- 787