Dagger 2 : Back to basics

Dagger 2 : Back to basics

Slides de mon talk sur Dagger 2 à la Droidcon Paris.

05dd369062f7c4e450e1e08d1471da5b?s=128

Jeremie Martinez

November 10, 2015
Tweet

Transcript

  1. Dagger 2 Back to basics @JeremMartinez 1 jeremie-martinez.com

  2. Inversion of Control “Don’t call us, we’ll call you…” 2

  3. Injection de dépendances JSR-330 Bob Lee Créateur de Guice Rod

    Johnson Créateur de Spring 3
  4. Pourquoi ? 4 Single Responsibility principle Meilleur découpage Facilement testable

    Meilleur maintenabilité Qualité de code
  5. Un peu d’Historique “Once upon a time…” 5

  6. Problèmes 6

  7. Problèmes BOILERPLATE 7 du code

  8. Problèmes LENT à l’initialisation et à l’injection 8

  9. Problèmes LOURD en mémoire et dans l’APK 9

  10. Problèmes FAIL au runtime 10

  11. Besoins Analyse statique Pas d’introspection Fail fast Aucun impact 11

  12. Dagger by Square 12

  13. Dagger 1 Créé en 2012 par Jesse Wilson (Guice) Encadré

    par Bob Lee (Guice, JSR330, Guava, CTO Square) Ouvert en mai 2013 Dernière version en Juillet 2014 (1.2.2) 13
  14. Bilan Rapide et facile JSR330 Compatible Utilisable sur Android Annotation

    Processing Ouvert à la communauté Java Introspection sur les classes Pas totalement au compile time Analyse pas totalement statique Proguard 14
  15. Dagger 2 by Google 15

  16. Dagger 2 Repris par la Java Core Librairies Team Assisté

    par Square Release en avril 2015 Résout les problématiques restantes de la version 1 16
  17. API 17

  18. API Fournir les dépendances : @Provides et @Module Demander des

    dépendances : @Inject Lier les modules et les injections : @Component Implémenter le pattern singleton : @Singleton 18
  19. 3 formes d’injection 19

  20. 3 formes d’injection Par constructeur 20

  21. Par constructeur public class ApiManager { private final Api api;

    @Inject public ApiManager(Api api) { this.api = api; } … } 21
  22. 3 formes d’injection Par constructeur Par field 22

  23. Par field public class ApiManager { @Inject Api api; …

    } 23
  24. 3 formes d’injection Par setter Par constructeur Par field 24

  25. Par field public class ApiManager { private Api api; @Inject

    public void setApi(Api api) { … } … } 25
  26. Par field public class ApiManager { private Api api; @Inject

    public void setApi(Api api) { … } … } Not supported 26
  27. Live coding 27

  28. SpeakersActivity SlotsActivity 28

  29. SpeakersActivity SlotsActivity SpeakerManager SlotManager 29

  30. SpeakersActivity SlotsActivity SpeakerManager SlotManager 30

  31. SpeakersActivity SlotsActivity SpeakerManager SlotManager ApiManager 31

  32. SpeakersActivity SlotsActivity SpeakerManager SlotManager ApiManager HttpClient Converter 32

  33. SpeakersActivity SlotsActivity SpeakerManager SlotManager ApiManager HttpClient EventBus Converter 33

  34. SpeakersActivity SlotsActivity SpeakerManager SlotManager ApiManager HttpClient EventBus Converter 34

  35. Pour aller plus loin… 35

  36. Scope “(sous-)Graphe local à durée de vie limitée” 36

  37. Scope - Exemple Application Scope UserScope UserScope Activity Scope ActivityScope

    ActivityScope Activity Scope ActivityScope ActivityScope DetailsActivity ListActivity LoginActivity LoginActivity ListActivity DetailsActivity Connexion Changement 37 Deconnexion
  38. Scope “(sous-)Graphe local à durée de vie limitée” Par exemple

    : • Singleton • PerActivity •PerUser • PerRequest 38
  39. Scope - API @Scope
 @Retention(RetentionPolicy.RUNTIME) public @interface UserScope{} Ne pas

    oublier d’annoter le composant ! 39
  40. Scope - Conclusion Clarté du graphe Mémoire Meilleure modélisation 40

  41. Lazy @Inject Lazy<ApiManager> lazyApi; ApiManager api = lazyApi.get(); Déplace l’initialisation

    de l’objet à sa première utilisation 41
  42. Named Injection par chaine de caractères Un seul qualifier par

    dépendance @Inject @Named("userPrefs") SharedPreferences userPrefs;
 @Inject @Named("appPrefs") SharedPreferences appPrefs; @Provides @Named("userPrefs") public SharedPreferences providesUserPrefs() @Provides @Named("appPrefs") public SharedPreferences providesAppPrefs() 42
  43. Tests “Tester c’est douter…” 43

  44. Tests - Dagger INUTILE “Si ça compile, ça marche !”

    44
  45. Tests - Unitaires public class ApiManager { private final EventBus

    bus; private final Api api; @Inject public ApiManager(EventBus bus, Api api) { … } … } 45
  46. Tests - Unitaires @RunWith(MockitoJUnitRunner.class) public class ApiManagerTest { @Mock EventBus

    bus; @Mock Api api; @InjectMocks ApiManager apiManager; @Test public should_call_backend() { … } … } 46
  47. Tests - Fonctionnels Pas de bonne solution 47

  48. Tests - Fonctionnels Build variant sur l’Android Gradle Plugin Mock

    des modules Dupliquer les configurations 48
  49. Conclusion 49

  50. Merci ! @JeremMartinez 50