Click here to load reader

Dagger 2: DI eficiente em Android - TDC 2015

  • View
    110

  • Download
    47

Embed Size (px)

Text of Dagger 2: DI eficiente em Android - TDC 2015

  1. 1. Dagger 2 Injeo de Dependncia no Android
  2. 2. rafaeltoledo.net @_rafaeltoledo Desenv. Android @ Concrete Solutions
  3. 3. O que Injeo de Dependncia?
  4. 4. Injeo de Dependncia (ou Dependency Injection, em ingls) um padro de desenvolvimento de programas de computadores utilizado quando necessrio manter baixo o nvel de acoplamento entre diferentes mdulos de um sistema. (...)
  5. 5. Nesta soluo as dependncias entre os mdulos no so definidas programaticamente, mas sim pela configurao de uma infraestrutura de software (container) que responsvel por "injetar" em cada componente suas dependncias declaradas. A Injeo de dependncia se relaciona com o padro Inverso de controle mas no pode ser considerada um sinnimo deste. Wikipedia, 2015
  6. 6. ?????????
  7. 7. Diz respeito a separao de onde os objetos so criados e onde so utilizados
  8. 8. Em vez de criar, voc pede
  9. 9. class UserController { void doLogic() { try { User user = RetrofitApi.getInstance().getUser(1); new UserDaoImpl().save(user); Logger.getForClass(UserController.class).log("Success"); } catch (IOException e) { Logger.getForClass(UserController.class).logException(e); } } }
  10. 10. class UserController { UserDaoImpl dao; Logger logger; UserApi api; void doLogic() { try { api = RetrofitApi.getInstance(); User user = api.getUser(1); dao = new UserDaoImpl(); dao.save(user); logger = Logger.getForClass(UserController.class); logger.log("Success"); } catch (IOException e) { logger = Logger.getForClass(UserController.class); logger.logException(e); } } }
  11. 11. class UserController { UserDao dao; // Interface! Logger logger; Api api; void doLogic() { try { if (api == null) api = RetrofitApi.getInstance(); User user = api.getUser(1); if (dao == null) dao = new UserDaoImpl(); dao.save(user); if (logger == null) logger = Logger.getForClass(UserController.class); logger.log("Success"); } catch (IOException e) { if (logger == null) logger = Logger.getForClass(UserController.class); logger.logException(e); } } }
  12. 12. class UserController { UserDao dao = new UserDaoImpl(); Logger logger = Logger.getForClass(UserController.class); Api api = RetrofitApi.getInstance(); void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  13. 13. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  14. 14. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  15. 15. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  16. 16. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  17. 17. UserDao UserController
  18. 18. UserDao UserController SessionManager
  19. 19. UserDao UserController SessionManager SignInController
  20. 20. UserDao UserController SessionManager SignInController CookieJob JobManager JobController PermissionChecker ReminderJob RoleController CandyShopper FruitJuicerJob UnknownController
  21. 21. UserDao UserController SessionManager SignInController CookieJob JobManager JobController PermissionChecker ReminderJob RoleController CandyShopper FruitJuicerJob UnknownController EM TODO LUGAR!
  22. 22. class UserDaoImpl implements UserDao { public UserDaoImpl() { //... } }
  23. 23. class UserDaoImpl implements UserDao { public UserDaoImpl(Context context) { //... } }
  24. 24. Alterao em todas as classes!
  25. 25. Alterao em todas as classes! Muito retrabalho!
  26. 26. Alterao em todas as classes! Muito retrabalho!
  27. 27. Alterao em todas as classes! Muito retrabalho!
  28. 28. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  29. 29. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  30. 30. class UserController { UserDao dao; Logger logger; Api api; public UserController(UserDao dao, Api api, Logger logger) { this.dao = dao; this.api = api; this.logger = logger; } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } }
  31. 31. DI: Separao do uso e criao de objetos
  32. 32. DI: Separao do uso e criao de objetos no h a necessidade de bibliotecas ou frameworks!
  33. 33. Desvantagem: muito boilerplate
  34. 34. Spring, Guice, Dagger 1 & cia #oldbutgold
  35. 35. Spring, Guice, Dagger 1 & cia #oldbutnot
  36. 36. Dagger 2
  37. 37. Dagger 2?
  38. 38. Dagger 2 Fork do Dagger, da Square, feito pela Google Elimina todo o uso de reflections Construda sobre as anotaes javax. inject da especificao JSR-330
  39. 39. Dagger 2 Validao de todo o grafo de dependncias em tempo de compilao Menos flexvel, se comparado ao Dagger 1 - ex.: no possui module overriding Proguard configuration-free
  40. 40. Dagger 2 API enxuta! Cdigo gerado debugger-friendly Muito performtico google.github.io/dagger
  41. 41. public @interface Component { Class[] modules() default {}; Class[] dependencies() default {}; } public @interface Subcomponent { Class[] includes() default {}; } public @interface Module { Class[] includes() default {}; } public @interface Provides { } public @interface MapKey { boolean unwrapValue() default true; } public interface Lazy { T get(); }
  42. 42. // JSR-330 public @interface Inject { } public @interface Scope { } public @interface Qualifier { }
  43. 43. Como integro no meu projeto?
  44. 44. // build.gradle buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' } } allprojects { repositories { jcenter() } }
  45. 45. // build.gradle buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' } } allprojects { repositories { jcenter() } }
  46. 46. // build.gradle buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.6' } } allprojects { repositories { jcenter() } }
  47. 47. // build.gradle buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.6' } } allprojects { repositories { jcenter() } }
  48. 48. apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion '22.0.1' defaultConfig { applicationId 'net.rafaeltoledo.tdc2015' minSdkVersion 15 targetSdkVersion 22 versionCode 1 versionName '1.0' } } dependencies { compile 'com.android.support:appcompat-v7:22.2.1' }
  49. 49. apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 22 buildToolsVersion '22.0.1' defaultConfig { applicationId 'net.rafaeltoledo.tdc2015' minSdkVersion 15 targetSdkVersion 22 versionCode 1 versionName '1.0' } } dependencies { compile 'com.android.support:appcompat-v7:22.2.1' compile 'com.google.dagger:dagger:2.0.1' apt 'com.google.dagger:dagger-compiler:2.0.1' provided 'org.glassfish:javax.annotation:10.0-b28' }
  50. 50. apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 22 buildToolsVersion '22.0.1' defaultConfig { applicationId 'net.rafaeltoledo.tdc2015' minSdkVersion 15 targetSdkVersion 22 versionCode 1 versionName '1.0' } } dependencies { compile 'com.android.support:appcompat-v7:22.2.1' compile 'com.google.dagger:dagger:2.0.1' apt 'com.google.dagger:dagger-compiler:2.0.1' provided 'org.glassfish:javax.annotation:10.0-b28' // JSR-330 }
  51. 51. E pronto!
  52. 52. Vamos comear?
  53. 53. @Inject @Component @Module @Provides Dagger 2
  54. 54. @Inject Parte da JSR-330 Marca quais dependncias devem ser fornecidas pelo Dagger Pode aparecer de 3 formas no cdigo
  55. 55. public class TdcActivityPresenter { private TdcActivity activity; private TdcDataStore dataStore; @Inject public TdcActivityPresenter(TdcActivity activity, TdcDataStore dataStore) { this.activity = activity; this.dataStore = dataStore;