$30 off During Our Annual Pro Sale. View Details »

Dagger 2 : Back to basics

Dagger 2 : Back to basics

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

Jeremie Martinez

November 10, 2015
Tweet

More Decks by Jeremie Martinez

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

  4. Pourquoi ?
    4
    Single Responsibility principle
    Meilleur découpage
    Facilement testable
    Meilleur maintenabilité
    Qualité de code

    View Slide

  5. Un peu
    d’Historique
    “Once upon a time…”
    5

    View Slide

  6. Problèmes
    6

    View Slide

  7. Problèmes
    BOILERPLATE
    7
    du code

    View Slide

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

    View Slide

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

    View Slide

  10. Problèmes
    FAIL
    au runtime
    10

    View Slide

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

    View Slide

  12. Dagger
    by Square
    12

    View Slide

  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

    View Slide

  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

    View Slide

  15. Dagger 2
    by Google
    15

    View Slide

  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

    View Slide

  17. API
    17

    View Slide

  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

    View Slide

  19. 3 formes d’injection
    19

    View Slide

  20. 3 formes d’injection
    Par
    constructeur
    20

    View Slide

  21. Par constructeur
    public class ApiManager {
    private final Api api;
    @Inject
    public ApiManager(Api api) {
    this.api = api;
    }

    }
    21

    View Slide

  22. 3 formes d’injection
    Par
    constructeur
    Par field
    22

    View Slide

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

    }
    23

    View Slide

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

    View Slide

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

    }
    25

    View Slide

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

    }
    Not supported
    26

    View Slide

  27. Live coding
    27

    View Slide

  28. SpeakersActivity
    SlotsActivity
    28

    View Slide

  29. SpeakersActivity
    SlotsActivity
    SpeakerManager
    SlotManager
    29

    View Slide

  30. SpeakersActivity
    SlotsActivity
    SpeakerManager
    SlotManager
    30

    View Slide

  31. SpeakersActivity
    SlotsActivity
    SpeakerManager
    SlotManager
    ApiManager
    31

    View Slide

  32. SpeakersActivity
    SlotsActivity
    SpeakerManager
    SlotManager
    ApiManager
    HttpClient
    Converter
    32

    View Slide

  33. SpeakersActivity
    SlotsActivity
    SpeakerManager
    SlotManager
    ApiManager
    HttpClient
    EventBus
    Converter
    33

    View Slide

  34. SpeakersActivity
    SlotsActivity
    SpeakerManager
    SlotManager
    ApiManager
    HttpClient
    EventBus
    Converter
    34

    View Slide

  35. Pour aller
    plus loin…
    35

    View Slide

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

    View Slide

  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

    View Slide

  38. Scope
    “(sous-)Graphe local à durée de vie limitée”
    Par exemple :
    • Singleton
    • PerActivity
    •PerUser
    • PerRequest
    38

    View Slide

  39. Scope - API
    @Scope

    @Retention(RetentionPolicy.RUNTIME)
    public @interface UserScope{}
    Ne pas oublier d’annoter le composant !
    39

    View Slide

  40. Scope - Conclusion
    Clarté du graphe
    Mémoire
    Meilleure modélisation
    40

    View Slide

  41. Lazy
    @Inject Lazy lazyApi;
    ApiManager api = lazyApi.get();
    Déplace l’initialisation de l’objet à sa première utilisation
    41

    View Slide

  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

    View Slide

  43. Tests
    “Tester c’est douter…”
    43

    View Slide

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

    View Slide

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

    }
    45

    View Slide

  46. Tests - Unitaires
    @RunWith(MockitoJUnitRunner.class)
    public class ApiManagerTest {
    @Mock EventBus bus;
    @Mock Api api;
    @InjectMocks ApiManager apiManager;
    @Test
    public should_call_backend() { … }

    }
    46

    View Slide

  47. Tests - Fonctionnels
    Pas de bonne solution
    47

    View Slide

  48. Tests - Fonctionnels
    Build variant sur l’Android Gradle Plugin
    Mock des modules
    Dupliquer les configurations
    48

    View Slide

  49. Conclusion
    49

    View Slide

  50. Merci !
    @JeremMartinez
    50

    View Slide