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 with
    Dagger 2
    Jake Wharton

    View full-size slide

  2. Dependency Injection
    flickr.com/photos/sunsetnoir/6984108500

    View full-size slide

  3. Dependency Injection
    • No “new”, dependencies come to you
    flickr.com/photos/sunsetnoir/6984108500

    View full-size slide

  4. Dependency Injection
    • First and foremost a pattern

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  9. public class Tweeter {

    public void tweet(String tweet) {

    TwitterApi api = new TwitterApi();

    api.postTweet("JakeWharton", tweet);

    }

    }

    View full-size slide

  10. 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();

    }

    }

    View full-size slide

  11. 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!");

    View full-size slide

  12. public class TwitterApi {

    public void postTweet(String user, String tweet) {

    OkHttpClient client = new OkHttpClient();

    Request request = // TODO build POST request...

    client.newCall(request).execute();

    }

    }

    View full-size slide

  13. 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();

    }

    }

    View full-size slide

  14. 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();

    }

    }

    View full-size slide

  15. 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();

    }

    }

    View full-size slide

  16. 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();

    }

    }

    View full-size slide

  17. public class Tweeter {

    public void tweet(String tweet) {

    TwitterApi api = new TwitterApi();

    api.postTweet("JakeWharton", tweet);

    }
    }

    View full-size slide

  18. public class Tweeter {

    public void tweet(String tweet) {

    TwitterApi api = new TwitterApi(new OkHttpClient());

    api.postTweet("JakeWharton", tweet);

    }

    }

    View full-size slide

  19. public class Tweeter {

    public void tweet(String tweet) {

    TwitterApi api = new TwitterApi(new OkHttpClient());

    api.postTweet("JakeWharton", tweet);

    }

    }

    View full-size slide

  20. public class Tweeter {

    private final TwitterApi api = new TwitterApi(new OkHttpClient());


    public void tweet(String tweet) {

    api.postTweet("JakeWharton", tweet);

    }

    }

    View full-size slide

  21. public class Tweeter {

    private final TwitterApi api = new TwitterApi(new OkHttpClient());


    public void tweet(String tweet) {

    api.postTweet("JakeWharton", tweet);

    }

    }

    View full-size slide

  22. 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);

    }

    }

    View full-size slide

  23. 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);

    }

    }

    View full-size slide

  24. Tweeter tweeter = new Tweeter();

    tweeter.tweet("Hello, #Devoxx 2014!");

    View full-size slide

  25. Tweeter tweeter = new Tweeter("JakeWharton");

    tweeter.tweet("Hello, #Devoxx 2014!");

    View full-size slide

  26. Tweeter tweeter = new Tweeter("JakeWharton");

    tweeter.tweet("Hello, #Devoxx 2014!");

    View full-size slide

  27. 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");

    View full-size slide

  28. 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);

    }

    View full-size slide

  29. public class Timeline {

    private final List cache = 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) { /* ... */ }

    }

    View full-size slide

  30. public class Timeline {

    private final List 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 get() { /* ... */ }

    public void loadMore(int amount) { /* ... */ }

    }

    View full-size slide

  31. public class Timeline {

    private final List 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 get() { /* ... */ }

    public void loadMore(int amount) { /* ... */ }

    }

    View full-size slide

  32. 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);

    }

    }

    View full-size slide

  33. 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);

    }

    }

    View full-size slide

  34. 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);

    }

    }

    View full-size slide

  35. 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);

    }

    View full-size slide

  36. 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);

    }

    View full-size slide

  37. 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);

    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  40. Dependency Injection
    Twitter API
    Tweeter
    HTTP Client
    Tweeter
    • How do we avoid the boilerplate that comes with the pattern?

    View full-size slide

  41. Library Rescue
    • Spring
    • Guice
    • Dagger (v1)
    • PicoContainer
    • CDI
    • Others…

    View full-size slide

  42. Guice Dagger
    (v1)

    View full-size slide

  43. Guice
    • Developed at Google by Bob Lee, later Jesse Wilson, others.

    View full-size slide

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

    View full-size slide

  45. 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…

    View full-size slide

  46. 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.

    View full-size slide

  47. 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.

    View full-size slide

  48. Dagger (v1)
    • Developed at Square by Jesse Wilson advised by Bob Lee.

    View full-size slide

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

    View full-size slide

  50. 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.

    View full-size slide

  51. 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)

    View full-size slide

  52. 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.

    View full-size slide

  53. Dagger (v1)
    • Wide-spread, successful use in large Android applications.

    View full-size slide

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

    View full-size slide

  55. 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.

    View full-size slide

  56. 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.

    View full-size slide

  57. 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.

    View full-size slide

  58. Dagger (v2)
    • Proposed and implemented by Java Core Libraries team.

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  61. 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.

    View full-size slide

  62. Dagger API
    • @Module + @Provides: mechanism for providing dependencies.

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  65. 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.

    View full-size slide

  66. Providing Dependencies

    View full-size slide

  67. Providing Dependencies
    • Modules are classes whose methods provide dependencies.

    View full-size slide

  68. Providing Dependencies
    • Modules are classes whose methods provide dependencies.
    • @Module on the class.

    View full-size slide

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

    View full-size slide


  70. public class NetworkModule {


    OkHttpClient provideOkHttpClient() {

    return new OkHttpClient();

    }



    TwitterApi provideTwitterApi(OkHttpClient client) {

    return new TwitterApi(client);

    }

    }

    View full-size slide


  71. public class NetworkModule {


    OkHttpClient provideOkHttpClient() {

    return new OkHttpClient();

    }



    TwitterApi provideTwitterApi(OkHttpClient client) {

    return new TwitterApi(client);

    }

    }
    @Module

    View full-size slide


  72. public class NetworkModule {


    OkHttpClient provideOkHttpClient() {

    return new OkHttpClient();

    }



    TwitterApi provideTwitterApi(OkHttpClient client) {

    return new TwitterApi(client);

    }

    }
    @Module
    !
    !
    @Provides
    !
    !
    !
    !
    !
    !
    !
    @Provides

    View full-size slide


  73. public class NetworkModule {


    OkHttpClient provideOkHttpClient() {

    return new OkHttpClient();

    }



    TwitterApi provideTwitterApi(OkHttpClient client) {

    return new TwitterApi(client);

    }

    }
    @Module
    !
    !
    @Provides
    !
    !
    !
    !
    !
    !
    !
    @Provides
    !
    !
    @Singleton
    !
    !
    !
    !
    !
    !
    !
    @Singleton

    View full-size slide

  74. Providing Dependencies

    View full-size slide

  75. Providing Dependencies
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi

    View full-size slide

  76. Providing Dependencies
    OkHttpClient
    TwitterApi
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi

    View full-size slide

  77. Providing Dependencies
    OkHttpClient
    TwitterApi
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi

    View full-size slide

  78. Providing Dependencies
    OkHttpClient
    TwitterApi
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi
    TwitterApi provideTwitterApi(OkHttpClient client) {

    return new TwitterApi(client);

    }

    View full-size slide

  79. Providing Dependencies
    OkHttpClient
    TwitterApi
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi

    View full-size slide

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

    View full-size slide

  81. 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.

    View full-size slide


  82. public class TwitterModule {
















    }

    View full-size slide


  83. public class TwitterModule {
















    }
    @Module

    View full-size slide


  84. public class TwitterModule {
















    }


    private final String user;


    public TwitterModule(String user) {

    this.user = user;

    }
    @Module

    View full-size slide


  85. 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

    View full-size slide


  86. 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

    View full-size slide

  87. Providing Dependencies
    OkHttpClient
    TwitterApi
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi

    View full-size slide

  88. Providing Dependencies
    OkHttpClient
    TwitterApi
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi
    TwitterModule#provideTweeter
    TwitterModule#provideTimeline

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  102. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  106. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  121. Requesting Dependencies

    View full-size slide

  122. Requesting Dependencies
    • @Inject annotation required.

    View full-size slide

  123. Requesting Dependencies
    • @Inject annotation required.
    • Constructor, field, and method injection.

    View full-size slide

  124. Constructor Injection

    View full-size slide

  125. Constructor Injection
    • @Inject on a single constructor.

    View full-size slide

  126. Constructor Injection
    • @Inject on a single constructor.
    • Constructor parameters are dependencies.

    View full-size slide

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

    View full-size slide

  128. public class TwitterApplication {

    private final Tweeter tweeter;

    private final Timeline timeline;


    @Inject

    public TwitterApplication(Tweeter tweeter, Timeline timeline) {

    this.tweeter = tweeter;

    this.timeline = timeline;

    }


    // ...

    }

    View full-size slide

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

    View full-size slide

  130. 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.

    View full-size slide

  131. @Module

    public class NetworkModule {

    @Provides @Singleton

    OkHttpClient provideOkHttpClient() {

    return new OkHttpClient();

    }


    @Provides @Singleton

    TwitterApi provideTwitterApi(OkHttpClient client) {

    return new TwitterApi(client);

    }

    }

    View full-size slide

  132. @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);












    }

    }

    View full-size slide

  133. 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();

    }

    }

    View full-size slide

  134. 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

    View full-size slide

  135. 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

    View full-size slide

  136. Method Injection

    View full-size slide

  137. Method Injection
    • @Inject on methods.

    View full-size slide

  138. Method Injection
    • @Inject on methods.
    • Method parameters are dependencies.

    View full-size slide

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

    View full-size slide

  140. 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.

    View full-size slide

  141. public class TwitterApplication {

    private final Tweeter tweeter;

    private final Timeline timeline;


    @Inject

    public TwitterApplication(Tweeter tweeter, Timeline timeline) {

    this.tweeter = tweeter;

    this.timeline = timeline;

    }





    }

    View full-size slide

  142. 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);

    }

    View full-size slide

  143. 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);

    }

    View full-size slide

  144. Field Injection

    View full-size slide

  145. Field Injection
    • @Inject on fields for dependencies.

    View full-size slide

  146. Field Injection
    • @Inject on fields for dependencies.
    • Field may not be private or final.

    View full-size slide

  147. public class TwitterApplication {

    @Inject Tweeter tweeter;

    @Inject Timeline timeline;


    // ...

    }

    View full-size slide

  148. public class TwitterActivity extends Activity {

    @Inject Tweeter tweeter;

    @Inject Timeline timeline;


    // ...

    }

    View full-size slide

  149. public class TwitterProcessor extends AbstractProcessor {

    @Inject Tweeter tweeter;

    @Inject Timeline timeline;


    // ...

    }

    View full-size slide

  150. Field Injection
    • @Inject on fields for dependencies.
    • Field may not be private or final.

    View full-size slide

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

    View full-size slide

  152. 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.

    View full-size slide

  153. Components
    • Bridge between modules and injection.

    View full-size slide

  154. Components
    • Bridge between modules and injection.
    • The injector.

    View full-size slide

  155. @Component
    !
    public interface TwitterComponent {


    }

    View full-size slide

  156. @Component
    !
    public interface TwitterComponent {


    }
    (modules = {
    NetworkModule.class,

    TwitterModule.class,

    })

    View full-size slide

  157. @Component
    !
    public interface TwitterComponent {


    }
    (modules = {
    NetworkModule.class,

    TwitterModule.class,

    })
    @Singleton

    View full-size slide

  158. @Component





    Tweeter tweeter();

    Timeline timeline();
    !
    public interface TwitterComponent {


    }
    (modules = {
    NetworkModule.class,

    TwitterModule.class,

    })
    @Singleton

    View full-size slide

  159. TwitterComponent component = Dagger_TwitterComponent.builder()

    .networkModule(new NetworkModule())

    .twitterModule(new TwitterModule("JakeWharton"))

    .build();

    View full-size slide

  160. TwitterComponent component = Dagger_TwitterComponent.builder()

    .networkModule(new NetworkModule())

    .twitterModule(new TwitterModule("JakeWharton"))

    .build();
    !
    !
    !
    !
    !
    !
    Timeline timeline = component.timeline();
    !
    !
    !
    !

    Tweeter tweeter = component.tweeter();

    View full-size slide

  161. TwitterComponent component = Dagger_TwitterComponent.builder()


    .twitterModule(new TwitterModule("JakeWharton"))

    .build();
    !
    Tweeter tweeter = component.tweeter();

    .networkModule(new NetworkModule())

    .networkModule(new NetworkModule())



    !
    !
    Timeline timeline = component.timeline();

    View full-size slide

  162. TwitterComponent component = Dagger_TwitterComponent.builder()


    .twitterModule(new TwitterModule("JakeWharton"))

    .build();
    !
    Tweeter tweeter = component.tweeter();



    !
    !
    Timeline timeline = component.timeline();

    View full-size slide

  163. 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();

    View full-size slide

  164. 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);

    }

    }

    }

    View full-size slide

  165. @Singleton
    @Component(modules = {

    NetworkModule.class,

    TwitterModule.class,

    })

    interface TwitterComponent {

    TwitterApplication app();

    }

    View full-size slide

  166. @Singleton
    @Component(modules = {

    NetworkModule.class,

    TwitterModule.class,

    })

    interface TwitterComponent {

    TwitterApplication app();

    }
    TwitterComponent component = Dagger_TwitterComponent.builder()

    .twitterModule(new TwitterModule("JakeWharton"))

    .build();

    component.app().run();

    View full-size slide

  167. 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);

    }

    }
    }

    View full-size slide

  168. @Singleton
    @Component(modules = {

    NetworkModule.class,

    TwitterModule.class,

    })

    interface TwitterComponent {

    void injectApp(TwitterApplication app);
    }

    View full-size slide

  169. @Singleton
    @Component(modules = {

    NetworkModule.class,

    TwitterModule.class,

    })

    interface TwitterComponent {

    void injectApp(TwitterApplication app);
    }
    TwitterComponent component = Dagger_TwitterComponent.builder()

    .twitterModule(new TwitterModule("JakeWharton"))

    .build();

    View full-size slide

  170. @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();

    View full-size slide

  171. @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();

    View full-size slide

  172. @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);

    View full-size slide

  173. @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();

    View full-size slide

  174. @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);

    View full-size slide

  175. @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();

    View full-size slide

  176. @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();

    View full-size slide

  177. Components
    • Bridge between modules and injection.
    • The injector.

    View full-size slide

  178. Components
    • Bridge between modules and injection.
    • The injector.
    • Implementation of scopes.

    View full-size slide

  179. @Singleton

    @Component(modules = NetworkModule.class)

    public interface ApiComponent {



    }

    View full-size slide

  180. @Singleton

    @Component(modules = NetworkModule.class)

    public interface ApiComponent {



    }
    @Component(

    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }

    View full-size slide

  181. @Singleton

    @Component(modules = NetworkModule.class)

    public interface ApiComponent {



    }
    @Component(

    dependencies = ApiComponent.class,

    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }

    View full-size slide

  182. @Singleton

    @Component(modules = NetworkModule.class)

    public interface ApiComponent {



    }



    TwitterApi api();

    @Component(

    dependencies = ApiComponent.class,

    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }

    View full-size slide

  183. @Singleton

    @Component(modules = NetworkModule.class)

    public interface ApiComponent {
    TwitterApi api();
    }
    @Component(

    dependencies = ApiComponent.class,
    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }
    @Singleton

    View full-size slide

  184. @Singleton

    @Component(modules = NetworkModule.class)

    public interface ApiComponent {
    TwitterApi api();
    }
    @Component(

    dependencies = ApiComponent.class,
    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }
    @Singleton

    View full-size slide

  185. @Singleton

    @Component(modules = NetworkModule.class)

    public interface ApiComponent {
    TwitterApi api();
    }
    @Component(

    dependencies = ApiComponent.class,
    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }

    View full-size slide

  186. @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);

    }

    }

    View full-size slide

  187. @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);

    }

    }

    View full-size slide

  188. @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);

    }

    }

    View full-size slide

  189. ApiComponent apiComponent = Dagger_ApiComponent. builder().build();

    View full-size slide

  190. ApiComponent apiComponent = Dagger_ApiComponent. create();
    ApiComponent apiComponent = Dagger_ApiComponent.

    View full-size slide

  191. ApiComponent apiComponent = Dagger_ApiComponent. create();

    View full-size slide

  192. ApiComponent apiComponent = Dagger_ApiComponent. create();
    TwitterComponent twitterComponent = Dagger_TwitterComponent.builder()

    .apiComponent(apiComponent)

    .twitterModule(new TwitterModule("Jake Wharton"))

    .build();

    View full-size slide

  193. ApiComponent apiComponent = Dagger_ApiComponent. create();
    TwitterComponent twitterComponent = Dagger_TwitterComponent.builder()

    .apiComponent(apiComponent)

    .twitterModule(new TwitterModule("Jake Wharton"))

    .build();
    component.app().run();

    View full-size slide

  194. Scope Annotations

    View full-size slide

  195. Scope Annotations
    • Only create a single instance.

    View full-size slide

  196. Scope Annotations
    • Only create a single instance.
    • @Singleton is the “largest” scope.

    View full-size slide

  197. Scope Annotations
    • Only create a single instance.
    • @Singleton is the “largest” scope.
    • Custom annotations for semantic clarity, shorter lifetime.

    View full-size slide

  198. public @interface User {

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

    View full-size slide

  199. public @interface User {

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

    View full-size slide

  200. @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);

    }

    }

    View full-size slide

  201. @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);

    }

    }

    View full-size slide

  202. @Component(

    dependencies = ApiComponent.class,
    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }

    View full-size slide

  203. @Component(

    dependencies = ApiComponent.class,
    modules = TwitterModule.class

    )

    public interface TwitterComponent {

    TwitterApplication app();

    }
    @User

    View full-size slide

  204. OkHttpClient
    TwitterApi
    NetworkModule

    View full-size slide

  205. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent

    View full-size slide

  206. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent

    View full-size slide

  207. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi

    View full-size slide

  208. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi

    View full-size slide

  209. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi Tweeter
    Timeline
    TwitterModule

    View full-size slide

  210. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi Tweeter
    Timeline
    TwitterModule
    TwitterComponent

    View full-size slide

  211. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi Tweeter
    Timeline
    TwitterModule
    TwitterComponent

    View full-size slide

  212. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi Tweeter
    Timeline
    TwitterModule
    TwitterComponent
    TwitterApp

    View full-size slide

  213. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi Tweeter
    Timeline
    TwitterModule
    TwitterComponent
    TwitterApp

    View full-size slide

  214. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi Tweeter
    Timeline
    TwitterModule
    TwitterComponent
    TwitterApp

    View full-size slide

  215. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi

    View full-size slide

  216. OkHttpClient
    TwitterApi
    NetworkModule
    ApiComponent
    TwitterApi Tweeter
    Timeline
    TwitterModule
    TwitterComponent
    TwitterApp

    View full-size slide

  217. Under The Hood

    View full-size slide

  218. Under The Hood
    OkHttpClient
    TwitterApi
    NetworkModule#provideOkHttpClient
    NetworkModule#provideTwitterApi
    TwitterModule#provideTweeter
    TwitterModule#provideTimeline
    Tweeter
    Timeline

    View full-size slide

  219. @Module

    public class NetworkModule {

    @Provides @Singleton

    OkHttpClient provideOkHttpClient() {

    return new OkHttpClient();

    }


    @Provides @Singleton

    TwitterApi provideTwitterApi(OkHttpClient client) {

    return new TwitterApi(client);

    }

    }

    View full-size slide

  220. public class NetworkModule {

    OkHttpClient provideOkHttpClient() {}
    TwitterApi provideTwitterApi(OkHttpClient) {}

    }
    public final class NetworkModule_ProvideOkHttpClientFactory
    implements Factory {

    private final NetworkModule module;


    public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) { 

    this.module = module;

    }


    @Override

    public OkHttpClient get() { 

    return module.provideOkHttpClient();

    }

    }

    View full-size slide

  221. public class NetworkModule {

    OkHttpClient provideOkHttpClient() {}
    TwitterApi provideTwitterApi(OkHttpClient) {}

    }
    public final class NetworkModule_ProvideOkHttpClientFactory
    implements Factory {

    private final NetworkModule module;


    public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) { 

    this.module = module;

    }


    @Override

    public OkHttpClient get() { 

    return module.provideOkHttpClient();

    }

    }

    View full-size slide

  222. public class NetworkModule {

    OkHttpClient provideOkHttpClient() {}
    TwitterApi provideTwitterApi(OkHttpClient) {}

    }
    public final class NetworkModule_ProvideOkHttpClientFactory
    implements Factory {

    private final NetworkModule module;


    public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) { 

    this.module = module;

    }


    @Override

    public OkHttpClient get() { 

    return module.provideOkHttpClient();

    }

    }

    View full-size slide

  223. public class NetworkModule {

    OkHttpClient provideOkHttpClient() {}
    TwitterApi provideTwitterApi(OkHttpClient) {}

    }
    public final class NetworkModule_ProvideOkHttpClientFactory
    implements Factory {

    private final NetworkModule module;


    public NetworkModule_ProvideOkHttpClientFactory(NetworkModule module) {

    this.module = module;

    }


    @Override

    public OkHttpClient get() { 

    return module.provideOkHttpClient();

    }

    }

    View full-size slide

  224. 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 {

    private final NetworkModule module;

    private final Provider clientProvider;


    public NetworkModule_ProvideTwitterApiFactory(
    NetworkModule module, Provider clientProvider) {

    this.module = module;

    this.clientProvider = clientProvider;

    }


    @Override

    public TwitterApi get() {

    return module.provideTwitterApi(clientProvider.get());

    }

    }

    View full-size slide

  225. 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 {

    private final NetworkModule module;

    private final Provider clientProvider;


    public NetworkModule_ProvideTwitterApiFactory(
    NetworkModule module, Provider clientProvider) {

    this.module = module;

    this.clientProvider = clientProvider;

    }


    @Override

    public TwitterApi get() {

    return module.provideTwitterApi(clientProvider.get());

    }

    }

    View full-size slide

  226. 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 {

    private final NetworkModule module;

    private final Provider clientProvider;


    public NetworkModule_ProvideTwitterApiFactory(
    NetworkModule module, Provider clientProvider) {

    this.module = module;

    this.clientProvider = clientProvider;

    }


    @Override

    public TwitterApi get() {

    return module.provideTwitterApi(clientProvider.get());

    }

    }

    View full-size slide

  227. @Singleton

    @Component(modules = NetworkModule.class)

    interface ApiComponent {

    TwitterApi api();

    }

    View full-size slide

  228. 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;

    }

    }

    }

    View full-size slide

  229. 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;

    }

    }

    }

    View full-size slide

  230. interface ApiComponent {

    TwitterApi api();

    }
    public final class Dagger_ApiComponent implements ApiComponent {
















    }

    View full-size slide

  231. interface ApiComponent {

    TwitterApi api();

    }
    public final class Dagger_ApiComponent implements ApiComponent {

    private Provider provideOkHttpClientProvider;

    private Provider 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();

    }

    View full-size slide

  232. interface ApiComponent {

    TwitterApi api();

    }
    public final class Dagger_ApiComponent implements ApiComponent {

    private Provider provideOkHttpClientProvider;

    private Provider 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();

    }

    View full-size slide

  233. interface ApiComponent {

    TwitterApi api();

    }
    public final class Dagger_ApiComponent implements ApiComponent {

    private Provider provideOkHttpClientProvider;

    private Provider 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();

    }

    View full-size slide

  234. interface ApiComponent {

    TwitterApi api();

    }
    public final class Dagger_ApiComponent implements ApiComponent {

    private Provider provideOkHttpClientProvider;

    private Provider 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();

    }

    View full-size slide

  235. interface ApiComponent {

    TwitterApi api();

    }
    public final class Dagger_ApiComponent implements ApiComponent {

    private Provider provideOkHttpClientProvider;

    private Provider 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();

    }

    View full-size slide

  236. interface ApiComponent {

    TwitterApi api();

    }
    public final class Dagger_ApiComponent implements ApiComponent {

    private Provider provideOkHttpClientProvider;

    private Provider 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();

    }

    View full-size slide

  237. @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();

    }

    View full-size slide

  238. public final class TwitterModule_ProvideTweeterFactory
    implements Factory {

    private final TwitterModule module;

    private final Provider apiProvider;


    public TwitterModule_ProvideTweeterFactory(
    TwitterModule module, Provider apiProvider) {

    this.module = module;

    this.apiProvider = apiProvider;

    }


    @Override

    public Tweeter get() {

    return module.provideTweeter(apiProvider.get());

    }

    }

    View full-size slide

  239. public final class TwitterModule_ProvideTimelineFactory
    implements Factory {

    private final TwitterModule module;

    private final Provider apiProvider;


    public TwitterModule_ProvideTimelineFactory(
    TwitterModule module, Provider apiProvider) {

    this.module = module;

    this.apiProvider = apiProvider;

    }


    @Override

    public Timeline get() {

    return module.provideTimeline(apiProvider.get());

    }

    }

    View full-size slide

  240. public final class TwitterApplication_Factory
    implements Factory {

    private final Provider tweeterProvider;

    private final Provider timelineProvider;


    public TwitterApplication_Factory(
    Provider tweeterProvider,
    Provider timelineProvider) {

    this.tweeterProvider = tweeterProvider;

    this.timelineProvider = timelineProvider;

    }


    @Override

    public TwitterApplication get() {

    return new TwitterApplication(tweeterProvider.get(),
    timelineProvider.get());

    }

    }

    View full-size slide

  241. 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;

    }

    }

    View full-size slide

  242. 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;

    }

    }

    View full-size slide

  243. 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;

    }

    }

    View full-size slide

  244. public final class Dagger_TwitterComponent implements TwitterComponent {

    // ...


    private Dagger_TwitterComponent(Builder builder) {

    twitterModule = builder.twitterModule;

    apiComponent = builder.apiComponent;


    apiProvider = new Factory() {

    @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);

    }

    View full-size slide

  245. public final class Dagger_TwitterComponent implements TwitterComponent {

    // ...


    private Dagger_TwitterComponent(Builder builder) {

    twitterModule = builder.twitterModule;

    apiComponent = builder.apiComponent;


    apiProvider = new Factory() {

    @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);

    }

    View full-size slide

  246. Dagger_ApiComponent.create()

    View full-size slide

  247. Dagger_ApiComponent.create()
    new NetworkModule

    View full-size slide

  248. Dagger_ApiComponent.create()
    new NetworkModule
    new NetworkModule_ProvideOkHttpClientFactory
    new NetworkModule_ProvideTwitterApiFactory

    View full-size slide

  249. Dagger_ApiComponent.create()
    new NetworkModule
    new NetworkModule_ProvideOkHttpClientFactory
    new NetworkModule_ProvideTwitterApiFactory
    new TwitterModule("Jake Wharton")

    View full-size slide

  250. Dagger_ApiComponent.create()
    new NetworkModule
    new NetworkModule_ProvideOkHttpClientFactory
    new NetworkModule_ProvideTwitterApiFactory
    new TwitterModule("Jake Wharton")
    Dagger_TwitterComponent.builder()...build()

    View full-size slide

  251. Dagger_ApiComponent.create()
    new NetworkModule
    new NetworkModule_ProvideOkHttpClientFactory
    new NetworkModule_ProvideTwitterApiFactory
    new TwitterModule("Jake Wharton")
    Dagger_TwitterComponent.builder()...build()
    new Factory

    View full-size slide

  252. 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

    View full-size slide

  253. twitterComponent.app()

    View full-size slide

  254. twitterComponent.app()
    twitterApplicationProvider.get()

    View full-size slide

  255. twitterComponent.app()
    twitterApplicationProvider.get()
    tweeterProvider.get()
    apiProvider.get()
    apiComponent.api()

    View full-size slide

  256. twitterComponent.app()
    twitterApplicationProvider.get()
    tweeterProvider.get()
    apiProvider.get()
    provideTwitterApiProvider.get()
    networkModule.provideOkHttpClient()
    apiComponent.api()
    clientProvider.get()

    View full-size slide

  257. twitterComponent.app()
    twitterApplicationProvider.get()
    tweeterProvider.get()
    apiProvider.get()
    provideTwitterApiProvider.get()
    networkModule.provideOkHttpClient()
    apiComponent.api()
    clientProvider.get()
    new OkHttpClient()

    View full-size slide

  258. twitterComponent.app()
    twitterApplicationProvider.get()
    tweeterProvider.get()
    apiProvider.get()
    provideTwitterApiProvider.get()
    networkModule.provideOkHttpClient()
    networkModule.provideTwitterApi(..)
    apiComponent.api()
    clientProvider.get()
    new OkHttpClient()

    View full-size slide

  259. twitterComponent.app()
    twitterApplicationProvider.get()
    tweeterProvider.get()
    apiProvider.get()
    provideTwitterApiProvider.get()
    networkModule.provideOkHttpClient()
    networkModule.provideTwitterApi(..)
    apiComponent.api()
    clientProvider.get()
    new OkHttpClient()
    new TwitterApi(..)

    View full-size slide

  260. twitterComponent.app()
    twitterApplicationProvider.get()
    tweeterProvider.get()
    apiProvider.get()
    provideTwitterApiProvider.get()
    networkModule.provideOkHttpClient()
    twitterModule.provideTweeter(..)
    networkModule.provideTwitterApi(..)
    apiComponent.api()
    clientProvider.get()
    new OkHttpClient()
    new TwitterApi(..)

    View full-size slide

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

    View full-size slide

  262. 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()
    new OkHttpClient()
    new TwitterApi(..)
    new Tweeter(..)

    View full-size slide

  263. 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()
    new OkHttpClient()
    new TwitterApi(..)
    new Tweeter(..)

    View full-size slide

  264. 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(..)

    View full-size slide

  265. 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(..)

    View full-size slide

  266. 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(..)

    View full-size slide

  267. Annotation Processing

    View full-size slide

  268. Annotation Processing
    bit.ly/apt-bd

    View full-size slide

  269. public @interface Inject {}
    public @interface Qualifier {}
    public @interface Named {

    String value();

    }
    public interface Provider {

    T get();

    }
    public @interface Scope {}
    JSR 330
    public @interface Singleton {}

    View full-size slide

  270. 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 get(Class type);

    public abstract T inject(T instance);

    }
    public interface Lazy {

    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 {

    void injectMembers(T instance);

    }
    Dagger 1

    View full-size slide

  271. 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 get(Class type);

    public abstract T inject(T instance);

    }
    public interface Lazy {

    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 {

    void injectMembers(T instance);

    }
    Dagger 1
    public interface Lazy {

    T get();

    }
    public interface MembersInjector {

    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 get(Class type);

    public abstract T inject(T instance);

    }

    View full-size slide

  272. public @interface Component {

    Class>[] modules() default {};

    Class>[] dependencies() default {};

    }
    public interface Lazy {

    T get();

    }
    public @interface Module {

    Class>[] includes() default { };

    }
    public @interface Provides {

    }
    public @interface MapKey {

    boolean unwrapValue();

    }
    Dagger 2

    View full-size slide

  273. public @interface Component {

    Class>[] modules() default {};

    Class>[] dependencies() default {};

    }
    public interface Lazy {

    T get();

    }
    public @interface Module {

    Class>[] includes() default { };

    }
    public @interface Provides {

    }
    public @interface MapKey {

    boolean unwrapValue();

    }
    Dagger 2
    public interface Lazy {

    T get();

    }
    public @interface MapKey {

    boolean unwrapValue();

    }

    View full-size slide

  274. More Concepts

    View full-size slide

  275. More Concepts
    • Set and map bindings.

    View full-size slide

  276. More Concepts
    • Set and map bindings.
    • Asynchronous producers.

    View full-size slide

  277. More Concepts
    • Set and map bindings.
    • Asynchronous producers.
    • Testing and module overrides.

    View full-size slide

  278. More Concepts
    • Set and map bindings.
    • Asynchronous producers.
    • Testing and module overrides.
    • AutoFactory for assisted injection.

    View full-size slide

  279. github.com/google/dagger

    View full-size slide

  280. Questions?
    jakewharton
    jakewharton
    jakewharton
    twitter.com/
    google.com/+
    .com

    View full-size slide