Slide 1

Slide 1 text

Dagger Jake Wharton

Slide 2

Slide 2 text

Dependency Injection

Slide 3

Slide 3 text

Dependency Injection • Every single app has some form of dependency injection

Slide 4

Slide 4 text

Dependency Injection • Every single app has some form of dependency injection • Separate behavior of something from its required classes

Slide 5

Slide 5 text

Dependency Injection • Every single app has some form of dependency injection • Separate behavior of something from its required classes Tweeter

Slide 6

Slide 6 text

Dependency Injection • Every single app has some form of dependency injection • Separate behavior of something from its required classes Tweeter Twitter API

Slide 7

Slide 7 text

Dependency Injection • Every single app has some form of dependency injection • Separate behavior of something from its required classes Tweeter Twitter API HTTP Client

Slide 8

Slide 8 text

public  class  Tweeter  {      public  void  tweet(String  tweet)  {          TwitterApi  api  =  new  TwitterApi();          api.postTweet("JakeWharton",  tweet);      }   }

Slide 9

Slide 9 text

public  class  Tweeter  {      public  void  tweet(String  tweet)  {          TwitterApi  api  =  new  TwitterApi();          api.postTweet("JakeWharton",  tweet);      }   } public  class  TwitterApi  {      public  void  postTweet(String  user,  String  tweet)  {          OkHttpClient  client  =  new  OkHttpClient();          HttpUrlConnection  conn  =  client.open("...");          //  ...  POST  blah  blah  blah  ...      }   }

Slide 10

Slide 10 text

public  class  Tweeter  {      public  void  tweet(String  tweet)  {          TwitterApi  api  =  new  TwitterApi();          api.postTweet("JakeWharton",  tweet);      }   } Tweeter  tweeter  =  new  Tweeter();   tweeter.tweet("Hello,  #Dagger  Meetup!"); public  class  TwitterApi  {      public  void  postTweet(String  user,  String  tweet)  {          OkHttpClient  client  =  new  OkHttpClient();          HttpUrlConnection  conn  =  client.open("...");          //  ...  POST  blah  blah  blah  ...      }   }

Slide 11

Slide 11 text

public  class  TwitterApi  {      public  void  postTweet(String  user,  String  tweet)  {          OkHttpClient  client  =  new  OkHttpClient();          HttpUrlConnection  conn  =  client.open("...");          //  ...  POST  blah  blah  blah  ...      }   }

Slide 12

Slide 12 text

public  class  TwitterApi  {      private  final  OkHttpClient  client  =  new  OkHttpClient();          public  void  postTweet(String  user,  String  tweet)  {          HttpUrlConnection  conn  =  client.open("...");          //  ...  POST  blah  blah  blah  ...      }   }

Slide 13

Slide 13 text

public  class  TwitterApi  {      private  final  OkHttpClient  client;            public  TwitterApi(OkHttpClient  client)  {          this.client  =  client;      }          public  void  postTweet(String  user,  String  tweet)  {          HttpUrlConnection  conn  =  client.open("...");          //  ...  POST  blah  blah  blah  ...      }   }

Slide 14

Slide 14 text

public  class  Tweeter  {      public  void  tweet(String  tweet)  {          TwitterApi  api  =  new  TwitterApi();          api.postTweet("JakeWharton",  tweet);      }   }

Slide 15

Slide 15 text

public  class  Tweeter  {      public  void  tweet(String  tweet)  {          TwitterApi  api  =  new  TwitterApi(new  OkHttpClient());          api.postTweet("JakeWharton",  tweet);      }   }

Slide 16

Slide 16 text

public  class  Tweeter  {      private  final  TwitterApi  api  =  new  TwitterApi(new  OkHttpClient());            public  void  tweet(String  tweet)  {          api.postTweet("JakeWharton",  tweet);      }   }

Slide 17

Slide 17 text

public  class  Tweeter  {      private  final  TwitterApi  api  =  new  TwitterApi(new  OkHttpClient());      private  final  String  user;            public  Tweeter(String  user)  {          this.user  =  user;      }            public  void  tweet(String  tweet)  {          api.postTweet(user,  tweet);      }   }

Slide 18

Slide 18 text

Tweeter  tweeter  =  new  Tweeter();   tweeter.tweet("Hello,  #Dagger  Meetup!");

Slide 19

Slide 19 text

Tweeter  tweeter  =  new  Tweeter("JakeWharton");   tweeter.tweet("Hello,  #Dagger  Meetup!"); tweeter.tweet("Log  cabins!  #Dagger  @twoffice");   tweeter.tweet("mind  ==  blown.  #Dagger");   tweeter.tweet("Where’s  that  @jessewilson  character?");   tweeter.tweet("#Dagger,  #Dagger  bills  y’all");   tweeter.tweet("Leave  early  for  Beer  Hall,  anyone?  #Meetup  #Dagger");

Slide 20

Slide 20 text

Tweeter  tweeter  =  new  Tweeter("JakeWharton");   tweeter.tweet("Hello,  #Dagger  Meetup!"); tweeter.tweet("Log  cabins!  #Dagger  @twoffice");   tweeter.tweet("mind  ==  blown.  #Dagger");   tweeter.tweet("Where’s  that  @jessewilson  character?");   tweeter.tweet("#Dagger,  #Dagger  bills  y’all");   tweeter.tweet("Leave  early  for  Beer  Hall,  anyone?  #Meetup  #Dagger"); Timeline  timeline  =  new  Timeline("JakeWharton");   timeline.loadMore(20);   for  (Tweet  tweet  :  timeline.get())  {      System.out.println(tweet);   }

Slide 21

Slide 21 text

public  class  Timeline  {      private  final  List  tweetCache  =  new  ArrayList<>();      private  final  TwitterApi  api  =  new  TwitterApi(new  OkHttpClient());      private  final  String  user;            public  Timeline(String  user)  {          this.user  =  user;      }            public  List  get()  {  /*  ...  */  }      public  void  loadMore(int  amount)  {  /*  ...  */  }   }

Slide 22

Slide 22 text

public  class  Timeline  {      private  final  List  tweetCache  =  new  ArrayList<>();      private  final  TwitterApi  api;      private  final  String  user;            public  Timeline(TwitterApi  api,  String  user)  {          this.api  =  api;          this.user  =  user;      }            public  List  get()  {  /*  ...  */  }      public  void  loadMore(int  amount)  {  /*  ...  */  }   }

Slide 23

Slide 23 text

public  class  Tweeter  {      private  final  TwitterApi  api  =  new  TwitterApi(new  OkHttpClient());      private  final  String  user;            public  Tweeter(String  user)  {          this.user  =  user;      }            public  void  tweet(String  tweet)  {          api.postTweet(user,  tweet);      }   }

Slide 24

Slide 24 text

public  class  Tweeter  {      private  final  TwitterApi  api;      private  final  String  user;            public  Tweeter(TwitterApi  api,  String  user)  {          this.api  =  api;          this.user  =  user;      }            public  void  tweet(String  tweet)  {          api.postTweet(user,  tweet);      }   }

Slide 25

Slide 25 text

Tweeter  tweeter  =  new  Tweeter("JakeWharton");   tweeter.tweet("Hello,  #Dagger  Meetup!");   ! Timeline  timeline  =  new  Timeline("JakeWharton");   timeline.loadMore(20);   for  (Tweet  tweet  :  timeline.get())  {      System.out.println(tweet);   }

Slide 26

Slide 26 text

OkHttpClient  client  =  new  OkHttpClient();   TwitterApi  api  =  new  TwitterApi(client);   String  user  =  "JakeWharton";       Tweeter  tweeter  =  new  Tweeter(api,  user);   tweeter.tweet("Managing  my  own  dependencies  :(");       Timeline  timeline  =  new  Timeline(api,  user);   timeline.loadMore(20);   for  (Tweet  tweet  :  timeline.get())  {      System.out.println(tweet);   }

Slide 27

Slide 27 text

Dependency Injection • Every single app has some form of dependency injection • Separate the behavior from the classes required to perform it Tweeter Twitter API HTTP Client

Slide 28

Slide 28 text

Dependency Injection • Every single app has some form of dependency injection • Separate the behavior from the classes required to perform it Tweeter Twitter API HTTP Client Timeline

Slide 29

Slide 29 text

Dependency Injection • Every single app has some form of dependency injection • Separate the behavior from the classes required to perform it • How do we avoid the boilerplate that comes with the pattern?

Slide 30

Slide 30 text

We used Guice

Slide 31

Slide 31 text

We used Guice • All of our Java services heavily use Guice

Slide 32

Slide 32 text

We used Guice • All of our Java services heavily use Guice • Powerful, dynamic, well-tested, wide-spread, etc...

Slide 33

Slide 33 text

We used Guice • All of our Java services heavily use Guice • Powerful, dynamic, well-tested, wide-spread, etc... • Canonical standard for dependency injection

Slide 34

Slide 34 text

We used Guice • All of our Java services heavily use Guice • Powerful, dynamic, well-tested, wide-spread, etc... • Canonical standard for dependency injection • Configuration problems fail at runtime

Slide 35

Slide 35 text

We used Guice • All of our Java services heavily use Guice • Powerful, dynamic, well-tested, wide-spread, etc... • Canonical standard for dependency injection • Configuration problems fail at runtime • Slow initialization, slow injection, memory problems

Slide 36

Slide 36 text

“Object Graph” Goals

Slide 37

Slide 37 text

“Object Graph” Goals • Static analysis of all dependencies and injections

Slide 38

Slide 38 text

“Object Graph” Goals • Static analysis of all dependencies and injections • Fail as early as possible (compile-time, not runtime)

Slide 39

Slide 39 text

“Object Graph” Goals • Static analysis of all dependencies and injections • Fail as early as possible (compile-time, not runtime) • Eliminate reflection on methods and annotations at runtime

Slide 40

Slide 40 text

“Object Graph” Goals • Static analysis of all dependencies and injections • Fail as early as possible (compile-time, not runtime) • Eliminate reflection on methods and annotations at runtime • Have negligible memory impact

Slide 41

Slide 41 text

“Object Graph” Development

Slide 42

Slide 42 text

“Object Graph” Development • ~5 weeks of heads-down work by Jesse Wilson

Slide 43

Slide 43 text

“Object Graph” Development • ~5 weeks of heads-down work by Jesse Wilson • Bob Lee served as technical advisor

Slide 44

Slide 44 text

“Object Graph” Development • ~5 weeks of heads-down work by Jesse Wilson • Bob Lee served as technical advisor • “Giant” boolean switch in our applications

Slide 45

Slide 45 text

“Object Graph” Development • ~5 weeks of heads-down work by Jesse Wilson • Bob Lee served as technical advisor • “Giant” boolean switch in our applications • 2 weeks after, dropped Guice completely

Slide 46

Slide 46 text

“Object Graph” Development • ~5 weeks of heads-down work by Jesse Wilson • Bob Lee served as technical advisor • “Giant” boolean switch in our applications • 2 weeks after, dropped Guice completely • Renamed to Dagger before first release

Slide 47

Slide 47 text

Dagger

Slide 48

Slide 48 text

Dagger Tweeter Twitter API HTTP Client User Manager Shared Preferences Account Manager

Slide 49

Slide 49 text

Dagger Tweeter Twitter API HTTP Client User Manager Shared Preferences DAG-er Account Manager

Slide 50

Slide 50 text

Dagger

Slide 51

Slide 51 text

Dagger • ObjectGraph: central dependency manager and injector

Slide 52

Slide 52 text

Dagger • ObjectGraph: central dependency manager and injector • @Module + @Provides: mechanism for providing dependencies

Slide 53

Slide 53 text

Dagger • ObjectGraph: central dependency manager and injector • @Module + @Provides: mechanism for providing dependencies • @Inject: mechanism for requesting dependencies

Slide 54

Slide 54 text

Dagger • ObjectGraph: central dependency manager and injector • @Module + @Provides: mechanism for providing dependencies • @Inject: mechanism for requesting dependencies • Plus some other sugar, magic, and conventions

Slide 55

Slide 55 text

Providing Dependencies

Slide 56

Slide 56 text

Providing Dependencies • Modules are classes that provide dependencies

Slide 57

Slide 57 text

Providing Dependencies • Modules are classes that provide dependencies • @Module annotation on the class

Slide 58

Slide 58 text

Providing Dependencies • Modules are classes that provide dependencies • @Module annotation on the class • @Provider annotation on a method indicates that its return type is a dependency

Slide 59

Slide 59 text

! public  class  NetworkModule  {   !    public  OkHttpClient  provideOkHttpClient()  {          return  new  OkHttpClient();      }       !    public  TwitterApi  provideTwitterApi(OkHttpClient  client)  {          return  new  TwitterApi(client);      }   ! }

Slide 60

Slide 60 text

! public  class  NetworkModule  {   !    public  OkHttpClient  provideOkHttpClient()  {          return  new  OkHttpClient();      }       !    public  TwitterApi  provideTwitterApi(OkHttpClient  client)  {          return  new  TwitterApi(client);      }   ! } @Module

Slide 61

Slide 61 text

! public  class  NetworkModule  {   !    public  OkHttpClient  provideOkHttpClient()  {          return  new  OkHttpClient();      }       !    public  TwitterApi  provideTwitterApi(OkHttpClient  client)  {          return  new  TwitterApi(client);      }   ! } ! !    @Provides   ! ! ! !    @Provides   ! ! ! @Module

Slide 62

Slide 62 text

! public  class  NetworkModule  {   !    public  OkHttpClient  provideOkHttpClient()  {          return  new  OkHttpClient();      }       !    public  TwitterApi  provideTwitterApi(OkHttpClient  client)  {          return  new  TwitterApi(client);      }   ! } ! !    @Provides   ! ! ! !    @Provides   ! ! ! ! !                        @Singleton   ! ! ! !                        @Singleton   ! ! ! @Module

Slide 63

Slide 63 text

Providing Dependencies

Slide 64

Slide 64 text

Providing Dependencies OkHttpClient TwitterApi

Slide 65

Slide 65 text

Providing Dependencies OkHttpClient TwitterApi NetworkModule#provideOkHttpClient NetworkModule#provideTwitterApi

Slide 66

Slide 66 text

Providing Dependencies OkHttpClient TwitterApi NetworkModule#provideOkHttpClient NetworkModule#provideTwitterApi

Slide 67

Slide 67 text

Providing Dependencies OkHttpClient TwitterApi NetworkModule#provideOkHttpClient NetworkModule#provideTwitterApi

Slide 68

Slide 68 text

Providing Dependencies • Modules are classes that provide dependencies • @Module annotation on the class provides static analysis hints • @Provider annotation on a method indicates that its return type is a dependency

Slide 69

Slide 69 text

Providing Dependencies • Modules are classes that provide dependencies • @Module annotation on the class provides static analysis hints • @Provider annotation on a method indicates that its return type is a dependency • Designed to be composed together

Slide 70

Slide 70 text

@Module   public  class  TwitterModule  {      private  final  String  user;            public  TwitterModule(String  user)  {          this.user  =  user;      }            @Provides  @Singleton      public  Tweeter  provideTweeter(TwitterApi  api)  {          return  new  Tweeter(api,  user);      }          @Provides  @Singleton      public  Timeline  provideTimeline(TwitterApi  api)  {          return  new  Timeline(api,  user);      }   }

Slide 71

Slide 71 text

Providing Dependencies OkHttpClient   TwitterApi NetworkModule#provideOkHttpClient   NetworkModule#provideTwitterApi

Slide 72

Slide 72 text

Providing Dependencies OkHttpClient   TwitterApi NetworkModule#provideOkHttpClient   NetworkModule#provideTwitterApi Tweeter Timeline TwitterModule#provideTweeter TwitterModule#provideTimeline

Slide 73

Slide 73 text

Requesting Dependencies

Slide 74

Slide 74 text

Requesting Dependencies • @Inject annotation required

Slide 75

Slide 75 text

Requesting Dependencies • @Inject annotation required • Field injection and constructor injection only

Slide 76

Slide 76 text

Constructor Injection

Slide 77

Slide 77 text

Constructor Injection • @Inject on a single constructor

Slide 78

Slide 78 text

Constructor Injection • @Inject on a single constructor • All constructor arguments are dependencies

Slide 79

Slide 79 text

Constructor Injection • @Inject on a single constructor • All constructor arguments are dependencies • Dependencies can be stored in private and final fields

Slide 80

Slide 80 text

public  class  TweeterApp  {      private  final  Tweeter  tweeter;      private  final  Timeline  timeline;            @Inject      public  TweeterApp(Tweeter  tweeter,  Timeline  timeline)  {          this.tweeter  =  tweeter;          this.timeline  =  timeline;      }            //  ...   }

Slide 81

Slide 81 text

Constructor Injection • @Inject on a single constructor • All constructor arguments are dependencies • Dependencies can be stored in private and final fields

Slide 82

Slide 82 text

Constructor Injection • @Inject on a single constructor • All constructor arguments are dependencies • Dependencies can be stored in private and final fields • Dagger must create the object

Slide 83

Slide 83 text

Constructor Injection • @Inject on a single constructor • All constructor arguments are dependencies • Dependencies can be stored in private and final fields • Dagger must create the object • @Provides not required for downstream injection

Slide 84

Slide 84 text

Field Injection

Slide 85

Slide 85 text

Field Injection • @Inject on fields which are dependencies

Slide 86

Slide 86 text

Field Injection • @Inject on fields which are dependencies • Field may not be private or final

Slide 87

Slide 87 text

public  class  TweeterApp  {      @Inject  Tweeter  tweeter;      @Inject  Timeline  timeline;            //  ...   }

Slide 88

Slide 88 text

public  class  TweeterActivity  extends  Activity  {      @Inject  Tweeter  tweeter;      @Inject  Timeline  timeline;            //  ...   }

Slide 89

Slide 89 text

Field Injection • @Inject on fields which are dependencies • Field may not be private or final

Slide 90

Slide 90 text

Field Injection • @Inject on fields which are dependencies • Field may not be private or final • Injection happens after the object is “alive”

Slide 91

Slide 91 text

Field Injection • @Inject on fields which are dependencies • Field may not be private or final • Injection happens after the object is “alive” • Object often must be responsible for injecting itself

Slide 92

Slide 92 text

The ObjectGraph

Slide 93

Slide 93 text

The ObjectGraph • Central module (dependency) manager

Slide 94

Slide 94 text

The ObjectGraph • Central module (dependency) manager • Injector

Slide 95

Slide 95 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  TwitterModule("JakeWharton")   );

Slide 96

Slide 96 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  TwitterModule("JakeWharton")   ); //  Using  constructor  injection:   TweeterApp  app  =  og.get(TweeterApp.class);

Slide 97

Slide 97 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  TwitterModule("JakeWharton")   ); //  Using  constructor  injection:   TweeterApp  app  =  og.get(TweeterApp.class); //  Using  field  injection:   TweeterApp  app  =  new  TweeterApp();   og.inject(app);

Slide 98

Slide 98 text

The ObjectGraph • Central module (dependency) manager • Injector

Slide 99

Slide 99 text

The ObjectGraph • Central module (dependency) manager • Injector • Can be extended to create “scopes”

Slide 100

Slide 100 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  TwitterModule("JakeWharton")   );

Slide 101

Slide 101 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule()   );

Slide 102

Slide 102 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  PersistenceModule(),          new  AccountModule()   );

Slide 103

Slide 103 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  PersistenceModule(),          new  AccountModule()   ); //  Inject  app  things  using  ‘og’...

Slide 104

Slide 104 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  PersistenceModule(),          new  AccountModule()   ); //  Later...   String  user  =  "JakeWharton"; //  Inject  app  things  using  ‘og’...

Slide 105

Slide 105 text

ObjectGraph  og  =  ObjectGraph.create(          new  NetworkModule(),          new  PersistenceModule(),          new  AccountModule()   ); //  Later...   String  user  =  "JakeWharton"; ObjectGraph  userOg  =  og.plus(new  TwitterModule(user)); //  Inject  app  things  using  ‘og’... //  Inject  user  things  using  ‘userOg’...

Slide 106

Slide 106 text

OkHttpClient TwitterApi NetworkModule

Slide 107

Slide 107 text

OkHttpClient TwitterApi NetworkModule PersistenceModule ! . . . AccountModule ! . . .

Slide 108

Slide 108 text

OkHttpClient TwitterApi NetworkModule PersistenceModule ! . . . AccountModule ! . . . og

Slide 109

Slide 109 text

OkHttpClient TwitterApi NetworkModule PersistenceModule ! . . . AccountModule ! . . . UserModule Tweeter Timeline og

Slide 110

Slide 110 text

OkHttpClient TwitterApi NetworkModule PersistenceModule ! . . . AccountModule ! . . . UserModule Tweeter Timeline og userOg

Slide 111

Slide 111 text

OkHttpClient TwitterApi NetworkModule PersistenceModule ! . . . AccountModule ! . . . UserModule Tweeter Timeline og userOg

Slide 112

Slide 112 text

OkHttpClient TwitterApi NetworkModule PersistenceModule ! . . . AccountModule ! . . . UserModule Tweeter Timeline og userOg

Slide 113

Slide 113 text

Android

Slide 114

Slide 114 text

Android • Entry objects are managed objects constructed by OS

Slide 115

Slide 115 text

Android • Entry objects are managed objects constructed by OS • Multiple services, activities, etc. required shared state

Slide 116

Slide 116 text

Android • Entry objects are managed objects constructed by OS • Multiple services, activities, etc. required shared state • Platform is very difficult to test

Slide 117

Slide 117 text

Android • Entry objects are managed objects constructed by OS • Multiple services, activities, etc. required shared state • Platform is very difficult to test • Build system allows for dynamic flavors and build types

Slide 118

Slide 118 text

Android • Entry objects are managed objects constructed by OS • Multiple services, activities, etc. required shared state • Platform is very difficult to test • Build system allows for dynamic flavors and build types • Many libraries require keeping singletons or long-lived objects

Slide 119

Slide 119 text

The ObjectGraph • Central module (dependency) manager • Injector • Can be extended to create “scopes”

Slide 120

Slide 120 text

The ObjectGraph • Central module (dependency) manager • Injector • Can be extended to create “scopes” • Eagerly or lazily created on the Application by convention

Slide 121

Slide 121 text

public  class  ExampleApp  extends  Application  {      private  ObjectGraph  objectGraph;          @Override  public  void  onCreate()  {          super.onCreate();   !        objectGraph  =  ObjectGraph.create(              new  ExampleModule()          );      }          public  ObjectGraph  getObjectGraph()  {          return  objectGraph;      }   }

Slide 122

Slide 122 text

public  class  ExampleActivity  extends  Activity  {      @Inject  Foo  foo;      @Inject  Bar  bar;          @Override      protected  void  onCreate(Bundle  savedInstanceState)  {          super.onCreate(savedInstanceState);              ExampleApp  app  =  (ExampleApp)  getApplication();          app.getObjectGraph().inject(this);              //  ...      }   }

Slide 123

Slide 123 text

The ObjectGraph • Central module (dependency) manager • Injector • Can be extended to create “scopes” • Eagerly or lazily created on the Application by convention

Slide 124

Slide 124 text

The ObjectGraph • Central module (dependency) manager • Injector • Can be extended to create “scopes” • Eagerly or lazily created on the Application by convention • Just another object instance

Slide 125

Slide 125 text

Listing Injection Points

Slide 126

Slide 126 text

Listing Injection Points • All injection points must be listed on a module

Slide 127

Slide 127 text

Listing Injection Points • All injection points must be listed on a module • Used for aggressive static analysis

Slide 128

Slide 128 text

Listing Injection Points • All injection points must be listed on a module • Used for aggressive static analysis • Potentially not needed for full compilation...

Slide 129

Slide 129 text

Listing Injection Points • All injection points must be listed on a module • Used for aggressive static analysis • Potentially not needed for full compilation... • ...but absolutely required for incremental compilation

Slide 130

Slide 130 text

@Module   public  class  ExampleModule  {      @Provides  @Singleton  Foo  provideFoo()  {          return  new  Foo();      }            @Provides  @Singleton  Bar  provideBar()  {          return  new  Bar();      }   }

Slide 131

Slide 131 text

@Module(      injects  =  {          ExampleActivity.class      }   )   public  class  ExampleModule  {      @Provides  @Singleton  Foo  provideFoo()  {          return  new  Foo();      }            @Provides  @Singleton  Bar  provideBar()  {          return  new  Bar();      }   }

Slide 132

Slide 132 text

Use in Android

Slide 133

Slide 133 text

Use in Android • Root ObjectGraph on Application

Slide 134

Slide 134 text

Use in Android • Root ObjectGraph on Application • Activities, services, fragments, views obtain and inject

Slide 135

Slide 135 text

Use in Android • Root ObjectGraph on Application • Activities, services, fragments, views obtain and inject • Modules and their “injects” segment parts of your app

Slide 136

Slide 136 text

Use in Android: .plus()

Slide 137

Slide 137 text

Use in Android: .plus() • Extend the graph with additional modules

Slide 138

Slide 138 text

Use in Android: .plus() • Extend the graph with additional modules • Allows creating “scopes” of dependencies

Slide 139

Slide 139 text

public  class  TweeterApp  extends  Application  {      private  ObjectGraph  objectGraph;          @Override  public  void  onCreate()  {          super.onCreate();   !        objectGraph  =  ObjectGraph.create(              new  NetworkModule(),              new  PersistenceModule(),              new  AccountModule(),          );      }          public  ObjectGraph  getObjectGraph()  {          return  objectGraph;      }   }

Slide 140

Slide 140 text

public  class  LandingActivity  extends  Activity  {      @Inject  UserManager  userManager;          @Override      protected  void  onCreate(Bundle  savedInstanceState)  {          super.onCreate(savedInstanceState);   !        ExampleApp  app  =  (ExampleApp)  getApplication();          app.getObjectGraph().inject(this);   !        if  (userManager.hasUser())  {              //  Start  TimelineActivity,  finish,  return...          }              //  Show  log  in  /  sign  up...      }   }

Slide 141

Slide 141 text

public  class  TimelineActivity  extends  Activity  {      @Inject  Timeline  timeline;      @Inject  Tweeter  tweeter;   !    @Override      protected  void  onCreate(Bundle  savedInstanceState)  {          super.onCreate(savedInstanceState);   !        ExampleApp  app  =  (ExampleApp)  getApplication();          ObjectGraph  og  =  app.getObjectGraph();   !        String  user  =  og.get(UserManager.class).getUser();          //  TODO  if  user  ==  null,  finish  and  start  LandingActivity...          og.plus(new  TwitterModule(user)).inject(this);              //  Set  up  timeline  and  tweeter  UI...      }   }

Slide 142

Slide 142 text

Use in Android: .plus()

Slide 143

Slide 143 text

Use in Android: .plus()

Slide 144

Slide 144 text

Sign Up Use in Android: .plus()

Slide 145

Slide 145 text

Use in Android: .plus() Forgot Password

Slide 146

Slide 146 text

@Module(      injects  =  {          SignUpView.class,  ForgotPasswordView.class      }   )   public  class  SignUpModule  {      private  final  SignUpActivity  signUpActivity;   !    public  SignUpModule(SignUpActivity  signUpActivity)  {          this.signUpActivity  =  signUpActivity;      }   !    @Provides  @Singleton  ActionBar  provideActionBar()  {          return  signUpActivity.getActionBar();      }   }

Slide 147

Slide 147 text

public  class  SignUpActivity  class  Activity  {      private  final  ObjectGraph  childOg;   !    @Override      protected  void  onCreate(Bundle  savedInstanceState)  {          super.onCreate(savedInstanceState);   !        ExampleApp  app  =  (ExampleApp)  getApplication();          ObjectGraph  og  =  app.getObjectGraph();   !        childOg  =  og.plus(new  SignUpModule(this));   !        //  Content  set  up  and  injection...      }   }

Slide 148

Slide 148 text

public  class  SignUpView  class  LinearLayout  {      @Inject  ActionBar  actionBar;   !    public  SignUpView(Context  context,  AttributeSet  attrs)  {          super(context,  attrs);          //  Note:  Injection  happens  by  parent  activity.      }   !    @Override  public  void  onAttachedToWindow()  {          super.onAttachedToWindow();          actionBar.setTitle(R.string.sign_up);      }   }

Slide 149

Slide 149 text

Use in Android: overrides

Slide 150

Slide 150 text

Use in Android: overrides • Modules whose dependencies override others

Slide 151

Slide 151 text

Use in Android: overrides • Modules whose dependencies override others • Only apply in the same ObjectGraph

Slide 152

Slide 152 text

Use in Android: overrides • Modules whose dependencies override others • Only apply in the same ObjectGraph • Useful for customizing flavors and testing

Slide 153

Slide 153 text

public  class  Timeline  {      private  final  List  tweetCache  =  new  ArrayList<>();      private  final  TwitterApi  api;      private  final  String  user;            public  Timeline(TwitterApi  api,  String  user)  {          this.api  =  api;          this.user  =  user;      }            public  List  get()  {  /*  ...  */  }      public  void  loadMore(int  amount)  {  /*  ...  */  }   }

Slide 154

Slide 154 text

public  class  MockTimeline  extends  Timeline  {      private  final  List  tweets  =  new  ArrayList<>();            @Inject  MockTimeline()  {          tweets.add(new  Tweet("MockUser",  "Hello,  mock  data!");      }            @Override  public  List  get()  {          return  tweets;      }   !    public  void  addTweet(Tweet  tweet)  {          tweets.add(new  Tweet("MockUser",  tweet),  0);      }   !    @Override  public  void  loadMore(int  amount)  {}   }

Slide 155

Slide 155 text

public  class  Tweeter  {      private  final  TwitterApi  api;      private  final  String  user;            public  Tweeter(TwitterApi  api,  String  user)  {          this.api  =  api;          this.user  =  user;      }            public  void  tweet(String  tweet)  {          api.postTweet(user,  tweet);      }   }

Slide 156

Slide 156 text

public  class  MockTweeter  extends  Tweeter  {      private  final  MockTimeline  timeline;            @Inject  MockTweeter(MockTimeline  timeline)  {          this.timeline  =  timeline;      }            @Override  public  void  tweet(String  tweet)  {          timeline.addTweet(tweet);      }   }

Slide 157

Slide 157 text

@Module(      overrides  =  true   )   public  class  MockTwitterModule  {      @Provides  @Singleton      public  Tweeter  provideTweeter(MockTweeter  mockTweeter)  {          return  mockTweeter;      }          @Provides  @Singleton      public  Timeline  provideTimeline(MockTimeline  mockTimeline)  {          return  mockTimeline;      }   }

Slide 158

Slide 158 text

ObjectGraph  og  =  ObjectGraph.create(      new  NetworkModule(),      new  TwitterModule("JakeWharton"),            new  MockTwitterModule()   );

Slide 159

Slide 159 text

Timeline  timeline  =  /*  injected  */   Tweeter  tweeter  =  /*  injected  */

Slide 160

Slide 160 text

Timeline  timeline  =  /*  injected  */   Tweeter  tweeter  =  /*  injected  */ for  (Tweet  tweet  :  timeline.get())  {      System.out.println(tweet);   }   //    MockUser:  Hello,  mock  data!

Slide 161

Slide 161 text

Timeline  timeline  =  /*  injected  */   Tweeter  tweeter  =  /*  injected  */ tweeter.tweet("Showing  off  more  mock  data!  #Dagger"); for  (Tweet  tweet  :  timeline.get())  {      System.out.println(tweet);   }   //    MockUser:  Hello,  mock  data!

Slide 162

Slide 162 text

Timeline  timeline  =  /*  injected  */   Tweeter  tweeter  =  /*  injected  */ for  (Tweet  tweet  :  timeline.get())  {      System.out.println(tweet);   }   //  MockUser:  Showing  off  more  mock  data!  #Dagger   //  MockUser:  Hello,  mock  data! tweeter.tweet("Showing  off  more  mock  data!  #Dagger"); for  (Tweet  tweet  :  timeline.get())  {      System.out.println(tweet);   }   //    MockUser:  Hello,  mock  data!

Slide 163

Slide 163 text

Mock Mode

Slide 164

Slide 164 text

Mock Mode • Modules which override all network-calling classes

Slide 165

Slide 165 text

Mock Mode • Modules which override all network-calling classes • Alternate implementations of network-calling classes which emulate a remote server but in-memory

Slide 166

Slide 166 text

Mock Mode • Modules which override all network-calling classes • Alternate implementations of network-calling classes which emulate a remote server but in-memory • Fake images and data included in debug builds

Slide 167

Slide 167 text

No content

Slide 168

Slide 168 text

No content

Slide 169

Slide 169 text

No content

Slide 170

Slide 170 text

//  src/release/java   ! final  class  Modules  {      static  Object[]  list()  {          return  new  Object[]  {              new  WalletModule()          };      }   }

Slide 171

Slide 171 text

//  src/release/java   ! final  class  Modules  {      static  Object[]  list()  {          return  new  Object[]  {              new  WalletModule()          };      }   } //  src/debug/java   ! final  class  Modules  {      static  Object[]  list()  {          return  new  Object[]  {              new  WalletModule(),              new  DebugWalletModule()          };      }   }

Slide 172

Slide 172 text

public  class  WalletApp  extends  Application  {      private  ObjectGraph  objectGraph;          @Override  public  void  onCreate()  {          super.onCreate();   !        objectGraph  =  ObjectGraph.create(Modules.list());      }          public  ObjectGraph  getObjectGraph()  {          return  objectGraph;      }   }

Slide 173

Slide 173 text

Debug Drawer

Slide 174

Slide 174 text

Debug Drawer • Provides quick access to developer options and information

Slide 175

Slide 175 text

Debug Drawer • Provides quick access to developer options and information • Completely hidden from normal UI

Slide 176

Slide 176 text

Debug Drawer • Provides quick access to developer options and information • Completely hidden from normal UI • Contains controls for changing app behavior

Slide 177

Slide 177 text

No content

Slide 178

Slide 178 text

No content

Slide 179

Slide 179 text

No content

Slide 180

Slide 180 text

No content

Slide 181

Slide 181 text

No content

Slide 182

Slide 182 text

U+2020 Sample App • Dagger • Retrofit • RxJava • Picasso • OkHttp • Butter Knife • Timber • Build Flavors

Slide 183

Slide 183 text

U+2020 Sample App • Dagger • Retrofit • RxJava • Picasso • OkHttp • Butter Knife • Timber • Build Flavors http://github.com/JakeWharton/u2020/

Slide 184

Slide 184 text

Dependency Injection

Slide 185

Slide 185 text

Dependency Injection • Do NOT ignore the pattern

Slide 186

Slide 186 text

Dependency Injection • Do NOT ignore the pattern • Do NOT make every class use the pattern

Slide 187

Slide 187 text

Dependency Injection • Do NOT ignore the pattern • Do NOT make every class use the pattern • Do NOT store dependencies as static fields

Slide 188

Slide 188 text

“Avoid Dependency Injection”

Slide 189

Slide 189 text

“Avoid Dependency Injection” Using a dependency injection framework such as Guice or RoboGuice may be attractive because they can simplify the code you write and provide an adaptive environment that's useful for testing and other configuration changes. However, these frameworks tend to perform a lot of process initialization by scanning your code for annotations, which can require significant amounts of your code to be mapped into RAM even though you don't need it. d.android.com/training/articles/memory.html#DependencyInjection

Slide 190

Slide 190 text

Dagger Performance

Slide 191

Slide 191 text

Dagger Performance • Annotation processor generates code to fulfill dependencies

Slide 192

Slide 192 text

Dagger Performance • Annotation processor generates code to fulfill dependencies • Happens automatically inside of javac

Slide 193

Slide 193 text

Dagger Performance • Annotation processor generates code to fulfill dependencies • Happens automatically inside of javac • Zero reflection on methods or fields

Slide 194

Slide 194 text

Dagger Performance • Annotation processor generates code to fulfill dependencies • Happens automatically inside of javac • Zero reflection on methods or fields • Debugger and developer friendly

Slide 195

Slide 195 text

The Future

Slide 196

Slide 196 text

The Future • Zero reflection... everywhere

Slide 197

Slide 197 text

The Future • Zero reflection... everywhere • Death to injects list

Slide 198

Slide 198 text

The Future • Zero reflection... everywhere • Death to injects list • Components encapsulate dependencies

Slide 199

Slide 199 text

The Future • Zero reflection... everywhere • Death to injects list • Components encapsulate dependencies • Scopes with dedicated annotations

Slide 200

Slide 200 text

The Future • Zero reflection... everywhere • Death to injects list • Components encapsulate dependencies • Scopes with dedicated annotations • http://squ.re/dagger2

Slide 201

Slide 201 text

http://square.github.io/dagger/

Slide 202

Slide 202 text

No content

Slide 203

Slide 203 text

Questions?

Slide 204

Slide 204 text

squareup.com/careers