dagger 2. right way to do dependency injection
TRANSCRIPT
![Page 1: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/1.jpg)
Dagger 2. Right way to do Dependency Injections
by Anton Minashkin
![Page 2: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/2.jpg)
Usual JAVA codepublic class Payroll { ...
public long getWithholding(long payInDollars) { ... return withholding; }
public long getAfterTaxPay(Employee employee) { long basePay = EmployeeDatabase.getInstance() .getBasePay(employee); long withholding = getWithholding(basePay);
return basePay - withholding; }}
![Page 3: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/3.jpg)
Usual JAVA codepublic class Payroll { ...
public long getWithholding(long payInDollars) { ... return withholding; }
public long getAfterTaxPay(Employee employee) { long basePay = EmployeeDatabase.getInstance() .getBasePay(employee); long withholding = getWithholding(basePay);
return basePay - withholding; }}
![Page 4: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/4.jpg)
Usual JAVA codepublic class Payroll { ...
public long getWithholding(long payInDollars) { ... return withholding; }
public long getAfterTaxPay(Employee employee) { long basePay = new EmployeeDatabase() .getBasePay(employee); long withholding = getWithholding(basePay);
return basePay - withholding; }}
![Page 5: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/5.jpg)
What is DI?In software engineering, dependency injection is a software design pattern that implements inversion of control for software libraries.
![Page 6: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/6.jpg)
What is DI?
![Page 7: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/7.jpg)
Say “Hi!” to DIpublic class Payroll { ... EmployeeDatabase mEmployeeDatabase; public Payroll(EmployeeDatabase employeeDatabase) { mEmployeeDatabase = employeeDatabase; } public long getWithholding(long payInDollars) { ... return withholding; } public long getAfterTaxPay(Employee employee) { long basePay = mEmployeeDatabase.getBasePay(employee); long withholding = getWithholding(basePay);
return basePay - withholding; }}
![Page 8: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/8.jpg)
Say “Hi!” to DIpublic class Payroll { ... EmployeeDatabase mEmployeeDatabase; public Payroll(EmployeeDatabase employeeDatabase) { mEmployeeDatabase = employeeDatabase; } public long getWithholding(long payInDollars) { ... return withholding; } public long getAfterTaxPay(Employee employee) { long basePay = mEmployeeDatabase.getBasePay(employee); long withholding = getWithholding(basePay);
return basePay - withholding; }}
![Page 9: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/9.jpg)
...but!Was:new Payroll().getAfterTaxPay(employee);
Now:new Payroll(EmployeeDatabase.getInstance()) .getAfterTaxPay(employee);
![Page 10: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/10.jpg)
...but!Was:new Payroll().getAfterTaxPay(employee);
Now:new Payroll(EmployeeDatabase.getInstance()) .getAfterTaxPay(employee);
![Page 11: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/11.jpg)
Java! To the rescue!
JSR-330
![Page 12: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/12.jpg)
JSR-330public class Payroll { ... @Inject public Payroll(EmployeeDatabase employeeDatabase) { mEmployeeDatabase = employeeDatabase; }...}
ORpublic class Payroll { ... @Inject EmployeeDatabase mEmployeeDatabase; ...}
![Page 13: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/13.jpg)
DI frameworks
● Google Guice● Spring DI● Java EE6 CDI● Dagger● etc.
![Page 14: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/14.jpg)
DI frameworks
● Google Guice● Spring DI● Java EE6 CDI● Dagger● etc.
![Page 15: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/15.jpg)
Dagger 2. History
Developed by SquareAdopted by Google (Dagger 2)
![Page 16: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/16.jpg)
Dagger 2. Main features
● Android friendly● JSR-330● Compile-time DI validation● Full stack code generation● User mimic code● Easy to debug & understand
![Page 17: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/17.jpg)
Dagger 2. APIclass Thermosiphon implements Pump { private final Heater heater;
@Inject Thermosiphon(Heater heater) { this.heater = heater; }
...}
![Page 18: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/18.jpg)
Dagger 2. APIclass CoffeeMaker { @Inject Heater heater; @Inject Pump pump;
...}
![Page 19: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/19.jpg)
Dagger 2. API@Moduleclass DripCoffeeModule { @Provides Heater provideHeater() { return new ElectricHeater(); }
@Provides Pump providePump(Thermosiphon pump) { return pump; }}
![Page 20: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/20.jpg)
Dagger 2. API@Component(modules = DripCoffeeModule.class)interface CoffeeShop { CoffeeMaker maker();}
![Page 21: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/21.jpg)
Dagger 2. APICoffeeShop coffeeShop = DaggerCoffeeShop.builder() .dripCoffeeModule(new DripCoffeeModule()) .build();
...
CoffeeShop coffeeShop = DaggerCoffeeShop.create();
![Page 22: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/22.jpg)
Dagger 2. APIpublic class CoffeeApp { public static void main(String[] args) { CoffeeShop coffeeShop = DaggerCoffeeShop.create(); coffeeShop.maker().brew(); }}
![Page 23: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/23.jpg)
Dagger 2. Scope@Provides @Singleton Heater provideHeater() { return new ElectricHeater();}
![Page 24: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/24.jpg)
Dagger 2. Lazyclass GridingCoffeeMaker { @Inject Lazy<Grinder> lazyGrinder;
public void brew() { while (needsGrinding()) { // Grinder created once on first call to .get() and cached. lazyGrinder.get().grind(); } }}
![Page 25: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/25.jpg)
Dagger 2. Provider Injectionclass 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(); ... } }}
![Page 26: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/26.jpg)
Dagger 2. Qualifiers@Qualifier@Documented@Retention(RUNTIME)public @interface Named { String value() default "";}
![Page 27: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/27.jpg)
Dagger 2. Qualifiersclass ExpensiveCoffeeMaker { @Inject @Named("water") Heater waterHeater; @Inject @Named("hot plate") Heater hotPlateHeater; ...}
![Page 28: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/28.jpg)
Dagger 2. Qualifiers@Provides @Named("hot plate") Heater provideHotPlateHeater() { return new ElectricHeater(70);}
@Provides @Named("water") Heater provideWaterHeater() { return new ElectricHeater(93);}
![Page 29: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/29.jpg)
Dagger 2. Compile-time validation@Moduleclass DripCoffeeModule { @Provides Heater provideHeater(Executor executor) { return new CpuHeater(executor); }}...
[ERROR] COMPILATION ERROR :[ERROR] error: java.util.concurrent.Executor cannot be provided without an @Provides-annotated method.
![Page 30: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/30.jpg)
Dagger 2. Generated code@Override public DataManager get() { DataManager provided = module.provideDataManager(authApiProvider.get(), articleApiProvider.get(), commentsApiProvider.get()); if (provided == null) { throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method"); } return provided; }
public static Factory<DataManager> create(DataManagerModule module, Provider<AuthApi> authApiProvider, Provider<ArticleApi> articleApiProvider, Provider<CommentApi> commentApiProvider) { return new DataManagerModule_ProvideDataManagerFactory(module, authApiProvider, articleApiProvider, commentApiProvider); }
![Page 31: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/31.jpg)
Dagger 2. Debugging
Here should be example of Guice stacktrace:VERY-VERY-BAD-STACKTRACE
And here is Dagger stacktrace:Mmmm… What a lovely stacktrace!
![Page 32: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/32.jpg)
Dagger 2. What should I inject?
● Anything that has constructor parameters● Anything that is out of local scope● Infrastructure● Anything that is shared between >1 objects● Different obj-graphs for different flavors
![Page 33: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/33.jpg)
Dagger 2. Where should I inject?public class MyApp extends Application {@Overridepublic void onCreate() {registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {... @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { inject(activity); }...});}
![Page 34: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/34.jpg)
Dagger 2
Example
![Page 35: Dagger 2. Right way to do Dependency Injection](https://reader030.vdocument.in/reader030/viewer/2022032513/55d37c23bb61ebd6188b45c5/html5/thumbnails/35.jpg)
Dagger 2
Questions?