Click here to load reader

Anton Minashkin Dagger 2 light

  • View
    224

  • Download
    0

Embed Size (px)

Text of Anton Minashkin Dagger 2 light

  1. 1. Dagger 2. Right way to do Dependency Injections by Anton Minashkin
  2. 2. Usual JAVA code public 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; } }
  3. 3. Usual JAVA code public 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; } }
  4. 4. Usual JAVA code public 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; } }
  5. 5. What is DI? In software engineering, dependency injection is a software design pattern that implements inversion of control for software libraries.
  6. 6. What is DI?
  7. 7. Say Hi! to DI public 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; } }
  8. 8. Say Hi! to DI public 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; } }
  9. 9. ...but! Was: new Payroll().getAfterTaxPay(employee); Now: new Payroll(EmployeeDatabase.getInstance()) .getAfterTaxPay(employee);
  10. 10. ...but! Was: new Payroll().getAfterTaxPay(employee); Now: new Payroll(EmployeeDatabase.getInstance()) .getAfterTaxPay(employee);
  11. 11. Java! To the rescue! JSR-330
  12. 12. JSR-330 public class Payroll { ... @Inject public Payroll(EmployeeDatabase employeeDatabase) { mEmployeeDatabase = employeeDatabase; } ... } OR public class Payroll { ... @Inject EmployeeDatabase mEmployeeDatabase; ... }
  13. 13. DI frameworks Google Guice Spring DI Java EE6 CDI Dagger etc.
  14. 14. DI frameworks Google Guice Spring DI Java EE6 CDI Dagger etc.
  15. 15. Dagger 2. History Developed by Square Adopted by Google (Dagger 2)
  16. 16. Dagger 2. Main features Android friendly JSR-330 Compile-time DI validation Full stack code generation User mimic code Easy to debug & understand
  17. 17. Dagger 2. API class Thermosiphon implements Pump { private final Heater heater; @Inject Thermosiphon(Heater heater) { this.heater = heater; } ... }
  18. 18. Dagger 2. API class CoffeeMaker { @Inject Heater heater; @Inject Pump pump; ... }
  19. 19. Dagger 2. API @Module class DripCoffeeModule { @Provides Heater provideHeater() { return new ElectricHeater(); } @Provides Pump providePump(Thermosiphon pump) { return pump; } }
  20. 20. Dagger 2. API @Component(modules = DripCoffeeModule.class) interface CoffeeShop { CoffeeMaker maker(); }
  21. 21. Dagger 2. API CoffeeShop coffeeShop = DaggerCoffeeShop.builder() .dripCoffeeModule(new DripCoffeeModule()) .build(); ... CoffeeShop coffeeShop = DaggerCoffeeShop.create();
  22. 22. Dagger 2. API public class CoffeeApp { public static void main(String[] args) { CoffeeShop coffeeShop = DaggerCoffeeShop.create(); coffeeShop.maker().brew(); } }
  23. 23. Dagger 2. Scope @Provides @Singleton Heater provideHeater() { return new ElectricHeater(); }
  24. 24. Dagger 2. Lazy class GridingCoffeeMaker { @Inject Lazy lazyGrinder; public void brew() { while (needsGrinding()) { // Grinder created once on first call to .get() and cached. lazyGrinder.get().grind(); } } }
  25. 25. Dagger 2. Provider Injection class BigCoffeeMaker { @Inject Provider 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(); ... } } }
  26. 26. Dagger 2. Qualifiers @Qualifier @Documented @Retention(RUNTIME) public @interface Named { String value() default ""; }
  27. 27. Dagger 2. Qualifiers class ExpensiveCoffeeMaker { @Inject @Named("water") Heater waterHeater; @Inject @Named("hot plate") Heater hotPlateHeater; ... }
  28. 28. Dagger 2. Qualifiers @Provides @Named("hot plate") Heater provideHotPlateHeater() { return new ElectricHeater(70); } @Provides @Named("water") Heater provideWaterHeater() { return new ElectricHeater(93); }
  29. 29. Dagger 2. Compile-time validation @Module class 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.
  30. 30. 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 create(DataManagerModule module, Provider authApiProvider, Provider articleApiProvider, Provider commentApiProvider) { return new DataManagerModule_ProvideDataManagerFactory(module, authApiProvider, articleApiProvider, commentApiProvider); }
  31. 31. Dagger 2. Debugging Here should be example of Guice stacktrace: VERY-VERY-BAD-STACKTRACE And here is Dagger stacktrace: Mmmm What a lovely stacktrace!
  32. 32. 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 Diferent obj-graphs for diferent flavors
  33. 33. Dagger 2. Where should I inject? public class MyApp extends Application { @Override public void onCreate() { registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { ... @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { inject(activity); } ... }); }
  34. 34. Dagger 2 Example
  35. 35. Dagger 2 Questions?
  36. 36. RTFM! http://google.github.io/dagger/ https://youtu.be/oK_XtfXPkqw anton.minashkin@outlook.com

Search related