Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dependency Injection with Dagger 2 (Devoxx 2014)

Dependency Injection with Dagger 2 (Devoxx 2014)

Dagger is a fast dependency injector for both Java and Android. Its second major version not only brings new features for parity with other frameworks but continues to push the boundaries of speed.

The concepts covered in this talk apply to both Java targeting the JVM and Android.

Video: https://parleys.com/play/5471cdd1e4b065ebcfa1d557/

Jake Wharton

November 13, 2014
Tweet

More Decks by Jake Wharton

Other Decks in Technology

Transcript

  1. Dependency Injection • First and foremost a pattern • Every

    single app has some form of dependency injection
  2. Dependency Injection • First and foremost a pattern • Every

    single app has some form of dependency injection Tweeter
  3. Dependency Injection • First and foremost a pattern • Every

    single app has some form of dependency injection Twitter API Tweeter
  4. Dependency Injection • First and foremost a pattern • Every

    single app has some form of dependency injection Twitter API Tweeter HTTP Client
  5. public class Tweeter {
 public void tweet(String tweet) {
 TwitterApi

    api = new TwitterApi();
 api.postTweet("JakeWharton", tweet);
 }
 }
  6. 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();
 Request request = // TODO build POST request...
 client.newCall(request).execute();
 }
 }
  7. 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();
 Request request = // TODO build POST request...
 client.newCall(request).execute();
 }
 } Tweeter tweeter = new Tweeter();
 tweeter.tweet("Hello, #Devoxx 2014!");
  8. public class TwitterApi {
 public void postTweet(String user, String tweet)

    {
 OkHttpClient client = new OkHttpClient();
 Request request = // TODO build POST request...
 client.newCall(request).execute();
 }
 }
  9. public class TwitterApi {
 private final OkHttpClient client = new

    OkHttpClient();
 
 public void postTweet(String user, String tweet) {
 Request request = // TODO build POST request...
 client.newCall(request).execute();
 }
 }
  10. public class TwitterApi {
 private final OkHttpClient client = new

    OkHttpClient();
 
 public void postTweet(String user, String tweet) {
 Request request = // TODO build POST request...
 client.newCall(request).execute();
 }
 }
  11. public class TwitterApi {
 private final OkHttpClient client;
 
 public

    TwitterApi(OkHttpClient client) {
 this.client = client;
 }
 
 public void postTweet(String user, String tweet) {
 Request request = // TODO build POST request...
 client.newCall(request).execute();
 }
 }
  12. public class TwitterApi {
 private final OkHttpClient client;
 
 public

    TwitterApi(OkHttpClient client) {
 this.client = client;
 }
 
 public void postTweet(String user, String tweet) {
 Request request = // TODO build POST request...
 client.newCall(request).execute();
 }
 }
  13. public class Tweeter {
 public void tweet(String tweet) {
 TwitterApi

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

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

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

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

    TwitterApi(new OkHttpClient());
 
 public void tweet(String tweet) {
 api.postTweet("JakeWharton", tweet);
 }
 }
  18. 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);
 }
 }
  19. 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);
 }
 }
  20. Tweeter tweeter = new Tweeter("JakeWharton");
 tweeter.tweet("Hello, #Devoxx 2014!"); ! 


    tweeter.tweet("#Hungover #Dagger"); ! 
 tweeter.tweet("Waffles, beer, diamonds, chocolate, and Dagger!"); ! 
 ! tweeter.tweet("Java Posse ain’t got nothing on #Dagger"); ! 
 ! ! tweeter.tweet("Are these the same slides from last year? #meta"); ! 
 ! ! ! tweeter.tweet("I need an injection of beer, amirite? #Dagger");
  21. Tweeter tweeter = new Tweeter("JakeWharton");
 tweeter.tweet("Hello, #Devoxx 2014!"); ! 


    tweeter.tweet("#Hungover #Dagger"); ! 
 tweeter.tweet("Waffles, beer, diamonds, chocolate, and Dagger!"); ! 
 ! tweeter.tweet("Java Posse ain’t got nothing on #Dagger"); ! 
 ! ! tweeter.tweet("Are these the same slides from last year? #meta"); ! 
 ! ! ! tweeter.tweet("I need an injection of beer, amirite? #Dagger"); Timeline timeline = new Timeline("JakeWharton");
 timeline.loadMore(20);
 for (Tweet tweet : timeline.get()) {
 System.out.println(tweet);
 }
  22. public class Timeline {
 private final List<Tweet> cache = new

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

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

    ArrayList<>();
 private final TwitterApi api;
 private final String user;
 
 public Timeline(TwitterApi api, String user) {
 this.api = api;
 this.user = user;
 }
 
 public List<Tweet> get() { /* ... */ }
 public void loadMore(int amount) { /* ... */ }
 }
  25. 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);
 }
 }
  26. 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);
 }
 }
  27. 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);
 }
 }
  28. Tweeter tweeter = new Tweeter("JakeWharton");
 tweeter.tweet("Hello, #Devoxx 2014!");
 
 Timeline

    timeline = new Timeline("JakeWharton");
 timeline.loadMore(20);
 for (Tweet tweet : timeline.get()) {
 System.out.println(tweet);
 }
  29. OkHttpClient client = new OkHttpClient();
 TwitterApi api = new TwitterApi(client);


    String user = "Jake Wharton";
 
 Tweeter tweeter = new Tweeter(api, user);
 tweeter.tweet("Hello, #Devoxx 2014!");
 
 Timeline timeline = new Timeline(api, user);
 timeline.loadMore(20);
 for (Tweet tweet : timeline.get()) {
 System.out.println(tweet);
 }
  30. OkHttpClient client = new OkHttpClient();
 TwitterApi api = new TwitterApi(client);


    String user = "Jake Wharton";
 
 Tweeter tweeter = new Tweeter(api, user);
 tweeter.tweet("Hello, #Devoxx 2014!");
 
 Timeline timeline = new Timeline(api, user);
 timeline.loadMore(20);
 for (Tweet tweet : timeline.get()) {
 System.out.println(tweet);
 }
  31. Dependency Injection • First and foremost a pattern • Every

    single app has some form of dependency injection Twitter API Tweeter HTTP Client
  32. Dependency Injection • First and foremost a pattern • Every

    single app has some form of dependency injection Twitter API Tweeter HTTP Client Tweeter
  33. Dependency Injection Twitter API Tweeter HTTP Client Tweeter • How

    do we avoid the boilerplate that comes with the pattern?
  34. Library Rescue • Spring • Guice • Dagger (v1) •

    PicoContainer • CDI • Others…
  35. Guice • Developed at Google by Bob Lee, later Jesse

    Wilson, others. • Adopted and maintained by Java Core Libraries team.
  36. Guice • Developed at Google by Bob Lee, later Jesse

    Wilson, others. • Adopted and maintained by Java Core Libraries team. • Powerful, dynamic, well-tested, wide-spread, etc…
  37. Guice • Developed at Google by Bob Lee, later Jesse

    Wilson, others. • Adopted and maintained by Java Core Libraries team. • Powerful, dynamic, well-tested, wide-spread, etc… • Configuration problems occur at runtime.
  38. Guice • Developed at Google by Bob Lee, later Jesse

    Wilson, others. • Adopted and maintained by Java Core Libraries team. • Powerful, dynamic, well-tested, wide-spread, etc… • Configuration problems occur at runtime. • Slow initialization, slow injection, memory concerns.
  39. Dagger (v1) • Developed at Square by Jesse Wilson advised

    by Bob Lee. • Initially targeted at highly resource constrained environments.
  40. Dagger (v1) • Developed at Square by Jesse Wilson advised

    by Bob Lee. • Initially targeted at highly resource constrained environments. • Static analysis of all dependencies and injection points.
  41. Dagger (v1) • Developed at Square by Jesse Wilson advised

    by Bob Lee. • Initially targeted at highly resource constrained environments. • Static analysis of all dependencies and injection points. • Fail as early as possible (compile-time, not runtime)
  42. Dagger (v1) • Developed at Square by Jesse Wilson advised

    by Bob Lee. • Initially targeted at highly resource constrained environments. • Static analysis of all dependencies and injection points. • Fail as early as possible (compile-time, not runtime) • Eliminate reflection on methods, fields, and annotations.
  43. Dagger (v1) • Wide-spread, successful use in large Android applications.

    • Triggers over-eager class loading on graph creation.
  44. Dagger (v1) • Wide-spread, successful use in large Android applications.

    • Triggers over-eager class loading on graph creation. • FQCN string-based keys in map-like data structure.
  45. Dagger (v1) • Wide-spread, successful use in large Android applications.

    • Triggers over-eager class loading on graph creation. • FQCN string-based keys in map-like data structure. • Lack of full static scope analysis and scope annotations.
  46. Dagger (v1) • Wide-spread, successful use in large Android applications.

    • Triggers over-eager class loading on graph creation. • FQCN string-based keys in map-like data structure. • Lack of full static scope analysis and scope annotations. • Still uses reflection to load generated classes.
  47. Dagger (v2) • Proposed and implemented by Java Core Libraries

    team. • Eliminate runtime library and generated code overhead.
  48. Dagger (v2) • Proposed and implemented by Java Core Libraries

    team. • Eliminate runtime library and generated code overhead. • Shift remaining runtime analysis to compile time.
  49. Dagger (v2) • Proposed and implemented by Java Core Libraries

    team. • Eliminate runtime library and generated code overhead. • Shift remaining runtime analysis to compile time. • Scoping with annotations and associated static analysis.
  50. Dagger API • @Module + @Provides: mechanism for providing dependencies.

    • @Inject: mechanism for requesting dependencies.
  51. Dagger API • @Module + @Provides: mechanism for providing dependencies.

    • @Inject: mechanism for requesting dependencies. • @Component: bridge between modules and injections
  52. Dagger API • @Module + @Provides: mechanism for providing dependencies.

    • @Inject: mechanism for requesting dependencies. • @Component: bridge between modules and injections • Plus some other sugar, magic, and conventions.
  53. Providing Dependencies • Modules are classes whose methods provide dependencies.

    • @Module on the class. • @Provides (and friends) on each method.
  54. 
 public class NetworkModule {
 
 OkHttpClient provideOkHttpClient() {
 return

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

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

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

    new OkHttpClient();
 }
 
 
 TwitterApi provideTwitterApi(OkHttpClient client) {
 return new TwitterApi(client);
 }
 } @Module ! ! @Provides ! ! ! ! ! ! ! @Provides ! ! @Singleton ! ! ! ! ! ! ! @Singleton
  58. Providing Dependencies • Modules are classes whose methods provide dependencies.

    • @Module on the class. • @Provides (and friends) on each method.
  59. Providing Dependencies • Modules are classes whose methods provide dependencies.

    • @Module on the class. • @Provides (and friends) on each method. ! ! ! • Designed to be partitioned and composed together.
  60. 
 public class TwitterModule {
 
 
 
 
 


    
 
 
 
 
 
 
 
 
 
 }
  61. 
 public class TwitterModule {
 
 
 
 
 


    
 
 
 
 
 
 
 
 
 
 } @Module
  62. 
 public class TwitterModule {
 
 
 
 
 


    
 
 
 
 
 
 
 
 
 
 } 
 
 private final String user;
 
 public TwitterModule(String user) {
 this.user = user;
 } @Module
  63. 
 public class TwitterModule {
 
 
 
 
 


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


    
 
 
 
 
 
 
 
 
 
 } 
 
 private final String user;
 
 public TwitterModule(String user) {
 this.user = user;
 } 
 public class TwitterModule {
 
 
 
 
 
 
 @Provides @Singleton
 Tweeter provideTweeter(TwitterApi api) {
 return new Tweeter(api, user);
 } 
 
 
 
 
 
 
 
 
 
 
 
 
 @Provides @Singleton
 Timeline provideTimeline(TwitterApi api) {
 return new Timeline(api, user);
 } @Module
  65. Providing Dependencies OkHttpClient TwitterApi NetworkModule#provideOkHttpClient NetworkModule#provideTwitterApi TwitterModule#provideTweeter TwitterModule#provideTimeline Tweeter Timeline

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

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

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

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

    Tweeter TwitterModule#provideTweeter TwitterApi NetworkModule#provideTwitterApi OkHttpClient OkHttpClient NetworkModule#provideTwitterApi TwitterApi
  70. Constructor Injection • @Inject on a single constructor. • Constructor

    parameters are dependencies. • Dependencies can be stored in private and final fields.
  71. public class TwitterApplication {
 private final Tweeter tweeter;
 private final

    Timeline timeline;
 
 @Inject
 public TwitterApplication(Tweeter tweeter, Timeline timeline) {
 this.tweeter = tweeter;
 this.timeline = timeline;
 }
 
 // ...
 }
  72. Constructor Injection • @Inject on a single constructor. • Constructor

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

    parameters are dependencies. • Dependencies can be stored in private and final fields. • Implicitly made available for downstream injection.
  74. @Module
 public class NetworkModule {
 @Provides @Singleton
 OkHttpClient provideOkHttpClient() {


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


    return new OkHttpClient();
 }
 
 @Provides @Singleton
 TwitterApi provideTwitterApi(OkHttpClient client) {
 return new TwitterApi(client);
 }
 } 
 
 
 
 
 
 
 @Provides @Singleton
 
 
 
 
 
 
 
 
 
 
 
 TwitterApi provideTwitterApi(OkHttpClient client) {
 
 
 
 
 
 
 
 
 
 
 
 return new TwitterApi(client);
 
 
 
 
 
 
 
 
 
 
 
 }
 }
  76. public class TwitterApi {
 private final OkHttpClient client;
 
 


    
 public TwitterApi(OkHttpClient client) {
 this.client = client;
 }
 
 public void postTweet(String user, String tweet) {
 Request request = // TODO build POST request ...
 client.newCall(request).execute();
 }
 }
  77. public class TwitterApi {
 private final OkHttpClient client;
 
 


    
 public TwitterApi(OkHttpClient client) {
 this.client = client;
 }
 
 public void postTweet(String user, String tweet) {
 Request request = // TODO build POST request ...
 client.newCall(request).execute();
 }
 } 
 
 
 @Inject
  78. public class TwitterApi {
 private final OkHttpClient client;
 
 


    
 public TwitterApi(OkHttpClient client) {
 this.client = client;
 }
 
 public void postTweet(String user, String tweet) {
 Request request = // TODO build POST request ...
 client.newCall(request).execute();
 }
 } 
 
 
 @Inject @Singleton
  79. Method Injection • @Inject on methods. • Method parameters are

    dependencies. • Injection happens after object is fully instantiated.
  80. Method Injection • @Inject on methods. • Method parameters are

    dependencies. • Injection happens after object is fully instantiated. • Only one valid use case: passing ‘this’ to a dependency.
  81. public class TwitterApplication {
 private final Tweeter tweeter;
 private final

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

    Timeline timeline;
 
 @Inject
 public TwitterApplication(Tweeter tweeter, Timeline timeline) {
 this.tweeter = tweeter;
 this.timeline = timeline;
 }
 
 
 
 
 } public class TwitterApplication {
 private final Tweeter tweeter;
 private final Timeline timeline;
 
 @Inject
 public TwitterApplication(Tweeter tweeter, Timeline timeline) {
 this.tweeter = tweeter;
 this.timeline = timeline;
 }
 
 
 
 
 } ! ! ! ! ! ! ! ! ! ! @Inject
 public void enableStreaming(Streaming streaming) {
 streaming.register(this);
 }
  83. public class TwitterApplication {
 private final Tweeter tweeter;
 private final

    Timeline timeline;
 
 @Inject
 public TwitterApplication(Tweeter tweeter, Timeline timeline) {
 this.tweeter = tweeter;
 this.timeline = timeline;
 }
 
 
 
 
 } ! ! ! ! ! ! ! ! ! ! @Inject
 public void enableStreaming(Streaming streaming) {
 streaming.register(this);
 }
  84. Field Injection • @Inject on fields for dependencies. • Field

    may not be private or final. • Injection happens after the object is fully instantiated.
  85. Field Injection • @Inject on fields for dependencies. • Field

    may not be private or final. • Injection happens after the object is fully instantiated. • Object is usually responsible for or aware of injection.
  86. @Component ! public interface TwitterComponent { 
 
 } (modules

    = { NetworkModule.class,
 TwitterModule.class,
 })
  87. @Component ! public interface TwitterComponent { 
 
 } (modules

    = { NetworkModule.class,
 TwitterModule.class,
 }) @Singleton
  88. @Component 
 
 
 
 
 Tweeter tweeter();
 Timeline timeline();

    ! public interface TwitterComponent { 
 
 } (modules = { NetworkModule.class,
 TwitterModule.class,
 }) @Singleton
  89. TwitterComponent component = Dagger_TwitterComponent.builder() 
 
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); !

    Tweeter tweeter = component.tweeter(); 
 .networkModule(new NetworkModule()) 
 .networkModule(new NetworkModule()) 
 
 
 ! ! Timeline timeline = component.timeline();
  90. TwitterComponent component = Dagger_TwitterComponent.builder() 
 
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); !

    Tweeter tweeter = component.tweeter(); 
 
 
 ! ! Timeline timeline = component.timeline();
  91. TwitterComponent component = Dagger_TwitterComponent.builder() 
 
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); !

    Tweeter tweeter = component.tweeter(); tweeter.tweet("Hello, #Devoxx 2014!"); timeline.loadMore(20);
 for (Tweet tweet : timeline.get()) {
 System.out.println(tweet);
 } 
 
 
 ! ! Timeline timeline = component.timeline();
  92. public class TwitterApplication implements Runnable {
 private final Tweeter tweeter;


    private final Timeline timeline;
 
 @Inject
 public TwitterApplication(Tweeter tweeter, Timeline timeline) {
 this.tweeter = tweeter;
 this.timeline = timeline;
 }
 
 @Override public void run() {
 tweeter.tweet("Hello #Devoxx 2014!");
 
 timeline.loadMore(20);
 for (Tweet tweet : timeline.get()) {
 System.out.println(tweet);
 }
 }
 }
  93. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    TwitterApplication app();
 } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build();
 component.app().run();
  94. public class TwitterApplication implements Runnable {
 @Inject Tweeter tweeter;
 @Inject

    Timeline timeline;
 
 @Override public void run() {
 tweeter.tweet("Hello #Devoxx 2014!");
 
 timeline.loadMore(20);
 for (Tweet tweet : timeline.get()) {
 System.out.println(tweet);
 }
 } }
  95. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    void injectApp(TwitterApplication app); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build();
  96. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    void injectApp(TwitterApplication app); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); TwitterApplication app = new TwitterApplication();
 component.injectApp(app);
 app.run();
  97. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    void injectActivity(TwitterActivity activity); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); TwitterActivity activity = // Android creates instance...
 component.injectActivity(activity); @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {
 void injectActivity(TwitterActivity activity); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build();
  98. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    void injectActivity(TwitterActivity activity); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); TwitterActivity activity = // Android creates instance...
 component.injectActivity(activity);
  99. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    void injectProcessor(TwitterProcessor processor); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); TwitterProcessor processor = // ServiceLoader creates instance...
 component.injectProcessor(processor); @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {
 void injectProcessor(TwitterProcessor processor); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build();
  100. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    void injectProcessor(TwitterProcessor processor); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); TwitterProcessor processor = // ServiceLoader creates instance...
 component.injectProcessor(processor);
  101. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    TwitterApplication injectApp(TwitterApplication app); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); TwitterApplication app = new TwitterApplication();
 component.injectApp(app).run(); @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {
 TwitterApplication injectApp(TwitterApplication app); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build();
  102. @Singleton @Component(modules = {
 NetworkModule.class,
 TwitterModule.class,
 })
 interface TwitterComponent {


    TwitterApplication injectApp(TwitterApplication app); } TwitterComponent component = Dagger_TwitterComponent.builder()
 .twitterModule(new TwitterModule("JakeWharton"))
 .build(); TwitterApplication app = new TwitterApplication();
 component.injectApp(app).run();
  103. @Singleton
 @Component(modules = NetworkModule.class)
 public interface ApiComponent { 
 


    
 } @Component( 
 modules = TwitterModule.class
 )
 public interface TwitterComponent {
 TwitterApplication app();
 }
  104. @Singleton
 @Component(modules = NetworkModule.class)
 public interface ApiComponent { 
 


    
 } @Component( 
 dependencies = ApiComponent.class, 
 modules = TwitterModule.class
 )
 public interface TwitterComponent {
 TwitterApplication app();
 }
  105. @Singleton
 @Component(modules = NetworkModule.class)
 public interface ApiComponent { 
 


    
 } 
 
 
 TwitterApi api();
 @Component( 
 dependencies = ApiComponent.class, 
 modules = TwitterModule.class
 )
 public interface TwitterComponent {
 TwitterApplication app();
 }
  106. @Singleton
 @Component(modules = NetworkModule.class)
 public interface ApiComponent { TwitterApi api();

    } @Component(
 dependencies = ApiComponent.class, modules = TwitterModule.class
 )
 public interface TwitterComponent {
 TwitterApplication app();
 } @Singleton
  107. @Singleton
 @Component(modules = NetworkModule.class)
 public interface ApiComponent { TwitterApi api();

    } @Component(
 dependencies = ApiComponent.class, modules = TwitterModule.class
 )
 public interface TwitterComponent {
 TwitterApplication app();
 } @Singleton
  108. @Singleton
 @Component(modules = NetworkModule.class)
 public interface ApiComponent { TwitterApi api();

    } @Component(
 dependencies = ApiComponent.class, modules = TwitterModule.class
 )
 public interface TwitterComponent {
 TwitterApplication app();
 }
  109. @Module
 public class TwitterModule {
 private final String user;
 


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


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


    public TwitterModule(String user) {
 this.user = user;
 }
 
 @Provides
 Tweeter provideTweeter(TwitterApi api) {
 return new Tweeter(api, user);
 }
 
 @Provides
 Timeline provideTimeline(TwitterApi api) {
 return new Timeline(api, user);
 }
 }
  112. Scope Annotations • Only create a single instance. • @Singleton

    is the “largest” scope. • Custom annotations for semantic clarity, shorter lifetime.
  113. public @interface User {
 } Scope Annotations • Only create

    a single instance. • @Singleton is the “largest” scope. • Custom annotations for semantic clarity, shorter lifetime.
  114. public @interface User {
 } @Scope Scope Annotations • Only

    create a single instance. • @Singleton is the “largest” scope. • Custom annotations for semantic clarity, shorter lifetime.
  115. @Module
 public class TwitterModule {
 private final String user;
 


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


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


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


    } public final class NetworkModule_ProvideOkHttpClientFactory implements Factory<OkHttpClient> { 
 private final NetworkModule module;
 
 public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) { 
 this.module = module;
 }
 
 @Override
 public OkHttpClient get() { 
 return module.provideOkHttpClient();
 }
 }
  119. public class NetworkModule {
 OkHttpClient provideOkHttpClient() {} TwitterApi provideTwitterApi(OkHttpClient) {}


    } public final class NetworkModule_ProvideOkHttpClientFactory implements Factory<OkHttpClient> { 
 private final NetworkModule module;
 
 public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) { 
 this.module = module;
 }
 
 @Override
 public OkHttpClient get() { 
 return module.provideOkHttpClient();
 }
 }
  120. public class NetworkModule {
 OkHttpClient provideOkHttpClient() {} TwitterApi provideTwitterApi(OkHttpClient) {}


    } public final class NetworkModule_ProvideOkHttpClientFactory implements Factory<OkHttpClient> { 
 private final NetworkModule module;
 
 public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) { 
 this.module = module;
 }
 
 @Override
 public OkHttpClient get() { 
 return module.provideOkHttpClient();
 }
 }
  121. public class NetworkModule {
 OkHttpClient provideOkHttpClient() {} TwitterApi provideTwitterApi(OkHttpClient) {}


    } public final class NetworkModule_ProvideOkHttpClientFactory implements Factory<OkHttpClient> { 
 private final NetworkModule module;
 
 public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) {
 this.module = module;
 }
 
 @Override
 public OkHttpClient get() { 
 return module.provideOkHttpClient();
 }
 }
  122. public class NetworkModule {
 OkHttpClient provideOkHttpClient() {} TwitterApi provideTwitterApi(OkHttpClient) {}


    } public final class NetworkModule_ProvideOkHttpClientFactory {
 public OkHttpClient get() { 
 return module.provideOkHttpClient();
 }
 } public final class NetworkModule_ProvideTwitterApiFactory implements Factory<TwitterApi> { 
 private final NetworkModule module;
 private final Provider<OkHttpClient> clientProvider;
 
 public NetworkModule_ProvideTwitterApiFactory( NetworkModule module, Provider<OkHttpClient> clientProvider) {
 this.module = module;
 this.clientProvider = clientProvider;
 }
 
 @Override
 public TwitterApi get() {
 return module.provideTwitterApi(clientProvider.get());
 }
 }
  123. public class NetworkModule {
 OkHttpClient provideOkHttpClient() {} TwitterApi provideTwitterApi(OkHttpClient) {}


    } public final class NetworkModule_ProvideOkHttpClientFactory {
 public OkHttpClient get() { 
 return module.provideOkHttpClient();
 }
 } public final class NetworkModule_ProvideTwitterApiFactory implements Factory<TwitterApi> { 
 private final NetworkModule module;
 private final Provider<OkHttpClient> clientProvider;
 
 public NetworkModule_ProvideTwitterApiFactory( NetworkModule module, Provider<OkHttpClient> clientProvider) {
 this.module = module;
 this.clientProvider = clientProvider;
 }
 
 @Override
 public TwitterApi get() {
 return module.provideTwitterApi(clientProvider.get());
 }
 }
  124. public class NetworkModule {
 OkHttpClient provideOkHttpClient() {} TwitterApi provideTwitterApi(OkHttpClient) {}


    } public final class NetworkModule_ProvideOkHttpClientFactory {
 public OkHttpClient get() { 
 return module.provideOkHttpClient();
 }
 } public final class NetworkModule_ProvideTwitterApiFactory implements Factory<TwitterApi> { 
 private final NetworkModule module;
 private final Provider<OkHttpClient> clientProvider;
 
 public NetworkModule_ProvideTwitterApiFactory( NetworkModule module, Provider<OkHttpClient> clientProvider) {
 this.module = module;
 this.clientProvider = clientProvider;
 }
 
 @Override
 public TwitterApi get() {
 return module.provideTwitterApi(clientProvider.get());
 }
 }
  125. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 // ... 
 public static final class Builder {
 private NetworkModule networkModule;
 
 public ApiComponent build() {
 if (networkModule == null) networkModule = new NetworkModule();
 return new Dagger_ApiComponent(this);
 }
 
 public Builder networkModule(NetworkModule networkModule) {
 if (networkModule == null) throw new NullPointerException();
 this.networkModule = networkModule;
 return this;
 }
 }
 }
  126. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 // ... 
 public static final class Builder {
 private NetworkModule networkModule;
 
 public ApiComponent build() {
 if (networkModule == null) networkModule = new NetworkModule();
 return new Dagger_ApiComponent(this);
 }
 
 public Builder networkModule(NetworkModule networkModule) {
 if (networkModule == null) throw new NullPointerException();
 this.networkModule = networkModule;
 return this;
 }
 }
 }
  127. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }
  128. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 private Provider<OkHttpClient> provideOkHttpClientProvider;
 private Provider<TwitterApi> provideTwitterApiProvider;
 
 private Dagger_ApiComponent(Builder builder) {
 NetworkModule networkModule = builder.networkModule;
 provideOkHttpClientProvider = ScopedProvider.create( new NetworkModule_ProvideOkHttpClientFactory(networkModule));
 provideTwitterApiProvider = ScopedProvider.create( new NetworkModule_ProvideTwitterApiFactory(networkModule, provideOkHttpClientProvider));
 }
 
 @Override
 public TwitterApi api() {
 return provideTwitterApiProvider.get();
 }
  129. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 private Provider<OkHttpClient> provideOkHttpClientProvider;
 private Provider<TwitterApi> provideTwitterApiProvider;
 
 private Dagger_ApiComponent(Builder builder) {
 NetworkModule networkModule = builder.networkModule;
 provideOkHttpClientProvider = ScopedProvider.create( new NetworkModule_ProvideOkHttpClientFactory(networkModule));
 provideTwitterApiProvider = ScopedProvider.create( new NetworkModule_ProvideTwitterApiFactory(networkModule, provideOkHttpClientProvider));
 }
 
 @Override
 public TwitterApi api() {
 return provideTwitterApiProvider.get();
 }
  130. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 private Provider<OkHttpClient> provideOkHttpClientProvider;
 private Provider<TwitterApi> provideTwitterApiProvider;
 
 private Dagger_ApiComponent(Builder builder) {
 NetworkModule networkModule = builder.networkModule;
 provideOkHttpClientProvider = ScopedProvider.create( new NetworkModule_ProvideOkHttpClientFactory(networkModule));
 provideTwitterApiProvider = ScopedProvider.create( new NetworkModule_ProvideTwitterApiFactory(networkModule, provideOkHttpClientProvider));
 }
 
 @Override
 public TwitterApi api() {
 return provideTwitterApiProvider.get();
 }
  131. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 private Provider<OkHttpClient> provideOkHttpClientProvider;
 private Provider<TwitterApi> provideTwitterApiProvider;
 
 private Dagger_ApiComponent(Builder builder) {
 NetworkModule networkModule = builder.networkModule;
 provideOkHttpClientProvider = ScopedProvider.create( new NetworkModule_ProvideOkHttpClientFactory(networkModule));
 provideTwitterApiProvider = ScopedProvider.create( new NetworkModule_ProvideTwitterApiFactory(networkModule, provideOkHttpClientProvider));
 }
 
 @Override
 public TwitterApi api() {
 return provideTwitterApiProvider.get();
 }
  132. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 private Provider<OkHttpClient> provideOkHttpClientProvider;
 private Provider<TwitterApi> provideTwitterApiProvider;
 
 private Dagger_ApiComponent(Builder builder) {
 NetworkModule networkModule = builder.networkModule;
 provideOkHttpClientProvider = ScopedProvider.create( new NetworkModule_ProvideOkHttpClientFactory(networkModule));
 provideTwitterApiProvider = ScopedProvider.create( new NetworkModule_ProvideTwitterApiFactory(networkModule, provideOkHttpClientProvider));
 }
 
 @Override
 public TwitterApi api() {
 return provideTwitterApiProvider.get();
 }
  133. interface ApiComponent {
 TwitterApi api();
 } public final class Dagger_ApiComponent

    implements ApiComponent {
 private Provider<OkHttpClient> provideOkHttpClientProvider;
 private Provider<TwitterApi> provideTwitterApiProvider;
 
 private Dagger_ApiComponent(Builder builder) {
 NetworkModule networkModule = builder.networkModule;
 provideOkHttpClientProvider = ScopedProvider.create( new NetworkModule_ProvideOkHttpClientFactory(networkModule));
 provideTwitterApiProvider = ScopedProvider.create( new NetworkModule_ProvideTwitterApiFactory(networkModule, provideOkHttpClientProvider));
 }
 
 @Override
 public TwitterApi api() {
 return provideTwitterApiProvider.get();
 }
  134. @Module
 public class TwitterModule {
 private final String user;
 


    public TwitterModule(String user) {
 this.user = user;
 }
 
 @Provides
 Tweeter provideTweeter(TwitterApi api) {
 return new Tweeter(api, user);
 }
 
 @Provides
 Timeline provideTimeline(TwitterApi api) {
 return new Timeline(api, user);
 }
 } @Component(
 dependencies = ApiComponent.class,
 modules = TwitterModule.class
 )
 interface TwitterComponent {
 TwitterApplication app();
 }
  135. public final class TwitterModule_ProvideTweeterFactory implements Factory<Tweeter> { 
 private final

    TwitterModule module;
 private final Provider<TwitterApi> apiProvider;
 
 public TwitterModule_ProvideTweeterFactory( TwitterModule module, Provider<TwitterApi> apiProvider) {
 this.module = module;
 this.apiProvider = apiProvider;
 }
 
 @Override
 public Tweeter get() {
 return module.provideTweeter(apiProvider.get());
 }
 }
  136. public final class TwitterModule_ProvideTimelineFactory implements Factory<Timeline> { 
 private final

    TwitterModule module;
 private final Provider<TwitterApi> apiProvider;
 
 public TwitterModule_ProvideTimelineFactory( TwitterModule module, Provider<TwitterApi> apiProvider) {
 this.module = module;
 this.apiProvider = apiProvider;
 }
 
 @Override
 public Timeline get() {
 return module.provideTimeline(apiProvider.get());
 }
 }
  137. public final class TwitterApplication_Factory implements Factory<TwitterApplication> { 
 private final

    Provider<Tweeter> tweeterProvider;
 private final Provider<Timeline> timelineProvider;
 
 public TwitterApplication_Factory( Provider<Tweeter> tweeterProvider, Provider<Timeline> timelineProvider) {
 this.tweeterProvider = tweeterProvider;
 this.timelineProvider = timelineProvider;
 }
 
 @Override
 public TwitterApplication get() {
 return new TwitterApplication(tweeterProvider.get(), timelineProvider.get());
 }
 }
  138. public static final class Builder {
 private TwitterModule twitterModule;
 private

    ApiComponent apiComponent;
 
 public TwitterComponent build() {
 if (twitterModule == null) throw new IllegalStateException("...");
 if (apiComponent == null) throw new IllegalStateException("...");
 return new Dagger_TwitterComponent(this);
 }
 
 public Builder twitterModule(TwitterModule twitterModule) {
 if (twitterModule == null) throw new NullPointerException("twitterModule");
 this.twitterModule = twitterModule;
 return this;
 }
 
 public Builder apiComponent(ApiComponent apiComponent) {
 if (apiComponent == null) throw new NullPointerException("apiComponent");
 this.apiComponent = apiComponent;
 return this;
 }
 }
  139. public static final class Builder {
 private TwitterModule twitterModule;
 private

    ApiComponent apiComponent;
 
 public TwitterComponent build() {
 if (twitterModule == null) throw new IllegalStateException("...");
 if (apiComponent == null) throw new IllegalStateException("...");
 return new Dagger_TwitterComponent(this);
 }
 
 public Builder twitterModule(TwitterModule twitterModule) {
 if (twitterModule == null) throw new NullPointerException("twitterModule");
 this.twitterModule = twitterModule;
 return this;
 }
 
 public Builder apiComponent(ApiComponent apiComponent) {
 if (apiComponent == null) throw new NullPointerException("apiComponent");
 this.apiComponent = apiComponent;
 return this;
 }
 }
  140. public static final class Builder {
 private TwitterModule twitterModule;
 private

    ApiComponent apiComponent;
 
 public TwitterComponent build() {
 if (twitterModule == null) throw new IllegalStateException("...");
 if (apiComponent == null) throw new IllegalStateException("...");
 return new Dagger_TwitterComponent(this);
 }
 
 public Builder twitterModule(TwitterModule twitterModule) {
 if (twitterModule == null) throw new NullPointerException("twitterModule");
 this.twitterModule = twitterModule;
 return this;
 }
 
 public Builder apiComponent(ApiComponent apiComponent) {
 if (apiComponent == null) throw new NullPointerException("apiComponent");
 this.apiComponent = apiComponent;
 return this;
 }
 }
  141. public final class Dagger_TwitterComponent implements TwitterComponent {
 // ...
 


    private Dagger_TwitterComponent(Builder builder) {
 twitterModule = builder.twitterModule;
 apiComponent = builder.apiComponent;
 
 apiProvider = new Factory<TwitterApi>() {
 @Override public TwitterApi get() {
 return apiComponent.api();
 }
 };
 
 provideTweeterProvider = new TwitterModule_ProvideTweeterFactory(twitterModule, apiProvider);
 provideTimelineProvider = new TwitterModule_ProvideTimelineFactory(twitterModule, apiProvider);
 twitterApplicationProvider = new TwitterApplication_Factory( provideTweeterProvider, provideTimelineProvider);
 }
  142. public final class Dagger_TwitterComponent implements TwitterComponent {
 // ...
 


    private Dagger_TwitterComponent(Builder builder) {
 twitterModule = builder.twitterModule;
 apiComponent = builder.apiComponent;
 
 apiProvider = new Factory<TwitterApi>() {
 @Override public TwitterApi get() {
 return apiComponent.api();
 }
 };
 
 provideTweeterProvider = new TwitterModule_ProvideTweeterFactory(twitterModule, apiProvider);
 provideTimelineProvider = new TwitterModule_ProvideTimelineFactory(twitterModule, apiProvider);
 twitterApplicationProvider = new TwitterApplication_Factory( provideTweeterProvider, provideTimelineProvider);
 }
  143. Dagger_ApiComponent.create() new NetworkModule new NetworkModule_ProvideOkHttpClientFactory new NetworkModule_ProvideTwitterApiFactory new TwitterModule("Jake Wharton")

    Dagger_TwitterComponent.builder()...build() new TwitterModule_ProvideTweeterFactory new TwitterModule_ProvideTimelineFactory new TwitterApplication_Factory new Factory<TwitterApi>
  144. twitterComponent.app() twitterApplicationProvider.get() tweeterProvider.get() apiProvider.get() provideTwitterApiProvider.get() networkModule.provideOkHttpClient() twitterModule.provideTweeter(..) timelineProvider.get() apiProvider.get() networkModule.provideTwitterApi(..)

    apiComponent.api() clientProvider.get() apiComponent.api() provideTwitterApiProvider.get() twitterModule.provideTimeline(..) new OkHttpClient() new TwitterApi(..) new Tweeter(..) new Timeline(..)
  145. twitterComponent.app() twitterApplicationProvider.get() tweeterProvider.get() apiProvider.get() provideTwitterApiProvider.get() networkModule.provideOkHttpClient() twitterModule.provideTweeter(..) timelineProvider.get() apiProvider.get() networkModule.provideTwitterApi(..)

    apiComponent.api() clientProvider.get() apiComponent.api() provideTwitterApiProvider.get() twitterModule.provideTimeline(..) new TwitterApplication(..) new OkHttpClient() new TwitterApi(..) new Tweeter(..) new Timeline(..)
  146. public @interface Inject {} public @interface Qualifier {} public @interface

    Named {
 String value();
 } public interface Provider<T> {
 T get();
 } public @interface Scope {} JSR 330 public @interface Singleton {}
  147. public abstract class ObjectGraph {
 public static ObjectGraph create(Object... modules)

    {}
 public abstract ObjectGraph plus(Object... modules);
 public abstract void validate();
 public abstract void injectStatics();
 public abstract <T> T get(Class<T> type);
 public abstract <T> T inject(T instance);
 } public interface Lazy<T> {
 T get();
 } public @interface Module {
 Class<?>[] injects() default { };
 Class<?>[] staticInjections() default { };
 Class<?>[] includes() default { };
 Class<?> addsTo() default Void.class;
 boolean overrides() default false;
 boolean complete() default true;
 boolean library() default true;
 } public @interface Provides {
 enum Type { UNIQUE, SET }
 Type type() default Type.UNIQUE;
 } public interface MembersInjector<T> {
 void injectMembers(T instance);
 } Dagger 1
  148. public abstract class ObjectGraph {
 public static ObjectGraph create(Object... modules)

    {}
 public abstract ObjectGraph plus(Object... modules);
 public abstract void validate();
 public abstract void injectStatics();
 public abstract <T> T get(Class<T> type);
 public abstract <T> T inject(T instance);
 } public interface Lazy<T> {
 T get();
 } public @interface Module {
 Class<?>[] injects() default { };
 Class<?>[] staticInjections() default { };
 Class<?>[] includes() default { };
 Class<?> addsTo() default Void.class;
 boolean overrides() default false;
 boolean complete() default true;
 boolean library() default true;
 } public @interface Provides {
 enum Type { UNIQUE, SET }
 Type type() default Type.UNIQUE;
 } public interface MembersInjector<T> {
 void injectMembers(T instance);
 } Dagger 1 public interface Lazy<T> {
 T get();
 } public interface MembersInjector<T> {
 void injectMembers(T instance);
 } public @interface Module {
 Class<?>[] injects() default { };
 Class<?>[] staticInjections() default { };
 Class<?>[] includes() default { };
 Class<?> addsTo() default Void.class;
 boolean overrides() default false;
 boolean complete() default true;
 boolean library() default true;
 } public abstract class ObjectGraph {
 public static ObjectGraph create(Object... modules) {}
 public abstract ObjectGraph plus(Object... modules);
 public abstract void validate();
 public abstract void injectStatics();
 public abstract <T> T get(Class<T> type);
 public abstract <T> T inject(T instance);
 }
  149. public @interface Component {
 Class<?>[] modules() default {};
 Class<?>[] dependencies()

    default {};
 } public interface Lazy<T> {
 T get();
 } public @interface Module {
 Class<?>[] includes() default { };
 } public @interface Provides {
 } public @interface MapKey {
 boolean unwrapValue();
 } Dagger 2
  150. public @interface Component {
 Class<?>[] modules() default {};
 Class<?>[] dependencies()

    default {};
 } public interface Lazy<T> {
 T get();
 } public @interface Module {
 Class<?>[] includes() default { };
 } public @interface Provides {
 } public @interface MapKey {
 boolean unwrapValue();
 } Dagger 2 public interface Lazy<T> {
 T get();
 } public @interface MapKey {
 boolean unwrapValue();
 }
  151. More Concepts • Set and map bindings. • Asynchronous producers.

    • Testing and module overrides. • AutoFactory for assisted injection.