Slide 1

Slide 1 text

Dagger 2 Manage dependencies in Google style Royce Mars Tech Lead @ DataArt

Slide 2

Slide 2 text

What is dependency injection?

Slide 3

Slide 3 text

Composition != inheritance Member variables need to be initialized

Slide 4

Slide 4 text

Creating objects with “new” keyword

Slide 5

Slide 5 text

Initializing new objects Via constructor parameters

Slide 6

Slide 6 text

Composition. The simplest example

Slide 7

Slide 7 text

Applying inheritance and composition When creating new objects

Slide 8

Slide 8 text

See dependencies in code ● Car depends on Engine. ● Engines may vary. ● Need different engines for testing and production

Slide 9

Slide 9 text

Dagger and JSR-330

Slide 10

Slide 10 text

Evolution of Dagger ● Dagger 2 - Google, Greg Kick ● Dagger - Square, Jake Wharton ● Guice - Google, Jesse Wilson

Slide 11

Slide 11 text

Inversion of control

Slide 12

Slide 12 text

Reflection vs Compile time Dagger 2 vs Dagger 1

Slide 13

Slide 13 text

JSR-330

Slide 14

Slide 14 text

Simple piece of magic...

Slide 15

Slide 15 text

Default constructor injection

Slide 16

Slide 16 text

Injection through parameters

Slide 17

Slide 17 text

So, how to make it work?

Slide 18

Slide 18 text

How does injection work?

Slide 19

Slide 19 text

Components & Modules Pic. by Miroslaw Stanek from Azimo http://frogermcs.github.io/dagger-graph-creation-performance/

Slide 20

Slide 20 text

Module declaration

Slide 21

Slide 21 text

Module annotations

Slide 22

Slide 22 text

Component declaration

Slide 23

Slide 23 text

Component annotations

Slide 24

Slide 24 text

Component initialization

Slide 25

Slide 25 text

Injection

Slide 26

Slide 26 text

Adding modules

Slide 27

Slide 27 text

Custom scopes

Slide 28

Slide 28 text

Objects lifecycle Pic. by Miroslaw Stanek from Azimo http://frogermcs.github.io/dagger-graph-creation-performance/

Slide 29

Slide 29 text

And again - Components & Modules Pic. by Miroslaw Stanek from Azimo http://frogermcs.github.io/dagger-graph-creation-performance/

Slide 30

Slide 30 text

This mysterious “plus”...

Slide 31

Slide 31 text

Declaring Subcomponent

Slide 32

Slide 32 text

Adding Module instance

Slide 33

Slide 33 text

Adding subcomponent

Slide 34

Slide 34 text

Managing subcomponents lifetime

Slide 35

Slide 35 text

Scope

Slide 36

Slide 36 text

@ActivityScope

Slide 37

Slide 37 text

@ActivityScope

Slide 38

Slide 38 text

Custom scope

Slide 39

Slide 39 text

Custom scope

Slide 40

Slide 40 text

Custom scope

Slide 41

Slide 41 text

So… what should we inject? ● Demo data sources / modules ● Presenters ● Singletons ● Test implementations ● All other dependencies :)

Slide 42

Slide 42 text

Best practices

Slide 43

Slide 43 text

New Android Injector

Slide 44

Slide 44 text

New Android Injector

Slide 45

Slide 45 text

Favor constructor injection over field injection ● Field injection requires non final and non private fields ● Forget an @Inject - get NullPointerException on a field ● Constructor injection = immutable and thread safe objects. Protect from partially constructed state ● For objects, constructed by the system (Activities, Fragments) - still use field injection

Slide 46

Slide 46 text

Favor constructor injection over field injection BAD:

Slide 47

Slide 47 text

Favor constructor injection over field injection BETTER:

Slide 48

Slide 48 text

Favor @Inject over @Provides ● @Provides methods should not duplicate the constructor boilerplate ● Code is easier to understand when coupled concerns are in one place

Slide 49

Slide 49 text

Favor @Inject over @Provides - no need in provides method in Module

Slide 50

Slide 50 text

Singletons should be extremely rare ● Singletons are useful when we need a centralized access to a mutable state ● Immutable objects doesn’t need to be a singleton

Slide 51

Slide 51 text

Singletons should be extremely rare BAD: GOOD:

Slide 52

Slide 52 text

Favor static @Provides methods ● The generated code can directly invoke the method instead of having to create a module instance. That method call can be inlined by the compiler ● All bindings being static will result in a sizable performance increase ● Make your modules abstract and Dagger will fail at compile time if one of the @Provides methods isn’t static

Slide 53

Slide 53 text

Favor static @Provides methods BAD:

Slide 54

Slide 54 text

Favor static @Provides methods

Slide 55

Slide 55 text

Use Kotlin, insert Koin :)

Slide 56

Slide 56 text

Home readings for Java ● Py “Keeping the Daggers Sharp” ● Mert Simsek “New Android Injector with Dagger 2” ● James Shvarts “Demystifying the new Dagger Android Injection API” ● Fernando Cejas “Tasting Dagger 2 on Android” ● Miroslaw Stanek “Dagger2 - graph creation performance” ● CodePath’s guide to Dagger2 ● Xoxol_89 @ Habrahabr “Dagger 2. Часть третья. Новые грани возможного” ● Dagger2 official page

Slide 57

Slide 57 text

Home readings for Kotlin Mobile Architecture Club ● Juan Ignacio Saravia, Keddit https://android.jlelse.eu/keddit-part-10-kotlin-dagger- 2-dependency-injection-a620052a7384 ● Antonio Leiva https://antonioleiva.com/dagger-android-kotlin/ ● Koin https://github.com/Ekito/koin

Slide 58

Slide 58 text

Thank you! :) @RoyceMars @DataArt