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

Sharpen your Code with Dagger

Sharpen your Code with Dagger

Slides from my talk at DevFest Yangon 2017

References I studied for this talk
- Future of Dependency Injection by Jake Wharton (https://www.youtube.com/watch?v=plK0zyRLIP8)
- Dependency Injection in Android with Dagger 2 from RayWenderLich blog
(https://www.raywenderlich.com/146804/dependency-injection-dagger-2)
- Keeping the Dagger sharp By Py
(https://medium.com/square-corner-blog/keeping-the-daggers-sharp-%EF%B8%8F-230b3191c3f)
- That Missing Guide: How to use Dagger2 by Zhuinden (https://medium.com/@Zhuinden/that-missing-guide-how-to-use-dagger2-ef116fbea97)

Aung Kyaw Paing

November 26, 2017
Tweet

More Decks by Aung Kyaw Paing

Other Decks in Programming

Transcript

  1. Sharpen your code
    with Dagger
    Aung Kyaw Paing

    View Slide

  2. Dependency?
    public class A {
    B b;
    public A() {
    this.b = new B();
    }
    }

    View Slide

  3. creates
    public class A {
    B b;
    public A() {
    this.b = new B();
    }
    }
    A B

    View Slide

  4. Dependency Injection
    public class A {
    B b;
    public A(B b) {
    this.b = b;
    }
    }

    View Slide

  5. public class A {
    B b;
    public A(B b) {
    this.b = b;
    }
    }
    Injected into
    A B

    View Slide

  6. S.O.L.I.D Principle
    • Single Responsibility Principle
    • Open/Closed Principle
    • Liskov Substitution Principle
    • Interface Segregation Principle
    • Dependency Inversion Principle

    View Slide

  7. S.O.L.I.D Principle
    • Single Responsibility Principle
    • Open/Closed Principle
    • Liskov Substitution Principle
    • Interface Segregation Principle
    • Dependency Inversion Principle

    View Slide

  8. Dependency Inversion Principle
    • Depend on abstractions. Do not depend
    on concretions.

    View Slide

  9. Network
    Abstraction
    Retrofit
    Volley Mock
    App

    View Slide

  10. Dependency Injection
    -A pattern

    View Slide

  11. public class FacebookService {
    public void postStatus(String status) {
    InterfaceFacebookApi apiInterface= RetrofitProvider.createFacebookApi();
    apiInterface.postStatus(status);
    }
    }

    View Slide

  12. public class PostStatus {
    public void execute(String status) {
    FacebookService service = new FacebookService();
    service.postStatus(status);
    }
    }
    public class FacebookService {
    public void postStatus(String status) {
    InterfaceFacebookApi apiInterface= RetrofitProvider.createFacebookApi();
    apiInterface.postStatus(status);
    }
    }

    View Slide

  13. PostStatus postStatus = new PostStatus();
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");

    View Slide

  14. public class FacebookService {
    public void postStatus(String status) {
    InterfaceFacebookApi apiInterface= RetrofitProvider.createFacebookApi();
    apiInterface.postStatus(status);
    }
    }

    View Slide

  15. public class FacebookService {
    InterfaceFacebookApi apiInterface = RetrofitProvider.createFacebookApi();
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    }

    View Slide

  16. public class FacebookService {
    InterfaceFacebookApi apiInterface;
    public FacebookService(InterfaceFacebookApi apiInterface) {
    this.apiInterface = apiInterface;
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    }

    View Slide

  17. public class PostStatus {
    public void execute(String status) {
    FacebookService service = new FacebookService();
    service.postStatus(status);
    }
    }

    View Slide

  18. public class PostStatus {
    public void execute(String status) {
    FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi());
    service.postStatus(status);
    }
    }

    View Slide

  19. public class PostStatus {
    FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi());
    public void execute(String status) {
    service.postStatus(status);
    }
    }

    View Slide

  20. PostStatus postStatus = new PostStatus();
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");

    View Slide

  21. PostStatus
    Facebook
    Service
    Retrofit

    View Slide

  22. PostStatus postStatus = new PostStatus();
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");

    View Slide

  23. PostStatus postStatus = new PostStatus();
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");
    PostImage postImage = new PostImage();
    postImage.execute("www.example.com/boston.jpg");
    postImage.execute("www.example.com/paris.jpg");

    View Slide

  24. public class FacebookService {
    InterfaceFacebookApi apiInterface;
    public FacebookService(InterfaceFacebookApi apiInterface) {
    this.apiInterface = apiInterface;
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    }

    View Slide

  25. public class FacebookService {
    InterfaceFacebookApi apiInterface;
    public FacebookService(InterfaceFacebookApi apiInterface) {
    this.apiInterface = apiInterface;
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }

    View Slide

  26. public class PostImage {
    FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi());
    public void execute(String imageUrl) {
    service.postImage(imageUrl);
    }
    }

    View Slide

  27. public class PostImage {
    FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi());
    public void execute(String imageUrl) {
    service.postImage(imageUrl);
    }
    }
    public class PostStatus {
    FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi());
    public void execute(String status) {
    service.postStatus(status);
    }
    }

    View Slide

  28. public class PostImage {
    FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi());
    public void execute(String imageUrl) {
    service.postImage(imageUrl);
    }
    }
    public class PostStatus {
    FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi());
    public void execute(String status) {
    service.postStatus(status);
    }
    }

    View Slide

  29. public class PostImage {
    FacebookService service;
    public PostImage(FacebookService service) {
    this.service = service;
    }
    public void execute(String imageUrl) {
    service.postImage(imageUrl);
    }
    }
    public class PostStatus {
    FacebookService service;
    public PostStatus(FacebookService service) {
    this.service = service;
    }
    public void execute(String status) {
    service.postStatus(status);
    }
    }

    View Slide

  30. PostStatus postStatus = new PostStatus();
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");
    PostImage postImage = new PostImage();
    postImage.execute("www.example.com/boston.jpg");
    postImage.execute("www.example.com/paris.jpg");

    View Slide

  31. InterfaceFacebookApi apiInterface = RetrofitProvider.createFacebookApi();
    FacebookService service = new FacebookService(apiInterface);
    PostStatus postStatus = new PostStatus(service);
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");
    PostImage postImage = new PostImage(service);
    postImage.execute("www.example.com/boston.jpg");
    postImage.execute("www.example.com/paris.jpg");

    View Slide

  32. PostStatus
    Facebook
    Service
    Retrofit

    View Slide

  33. PostStatus
    Facebook
    Service
    Retrofit
    PostImage

    View Slide

  34. DI comes at the cost of boilerplate

    View Slide

  35. Spring
    DI Framework

    View Slide

  36. - Developed by Pivotal Software
    - Written in XML
    - Runtime crashes
    - Untraceable
    Spring

    View Slide

  37. Spring Guice
    DI Framework

    View Slide

  38. - Developed at Google by Bob Lee, Jessie Wilson and others
    - Maintained by Java Core Lib team
    - Written in Java
    - Heavy Initialization
    - Untraceable
    - Runtime crashes
    Guice

    View Slide

  39. DI Framework
    Spring Guice Dagger 1

    View Slide

  40. - Developed by Jessie Wilson(Square)
    - Advised By Bob Lee
    - Written in Java
    - Targeted for resource limited environment
    - Uses reflection
    - Runtime crashes
    - No scoping
    Dagger 1

    View Slide

  41. DI Framework
    Spring Guice Dagger 1 Dagger 2

    View Slide

  42. - Developed by Java Core Lib Team
    - Written with Java
    - Compile time crashes
    - Eliminated overheads
    - Support Scoping
    Dagger 2

    View Slide

  43. Dagger 2 API
    @Module / @Provides
    - Provide dependencies

    View Slide

  44. Dagger 2 API
    @Module / @Provides
    - Provide dependencies
    @Inject
    - Request dependencies

    View Slide

  45. Dagger 2 API
    @Module / @Provides
    - Provide dependencies
    @Inject
    - Request dependencies
    @Component
    - Bridge modules and injections

    View Slide

  46. [email protected] is a class that holds related dependencies
    [email protected] is the method of module classes
    Dagger 2 API

    View Slide

  47. @Module public class NetworkModule {
    @Provides @Singleton Retrofit providesRetrofit() {
    return new Retrofit.Builder().build();
    }
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit.create(InterfaceFacebookApi.class));
    }
    }

    View Slide

  48. FacebookService
    NetworkModule#providesRetrofit
    NetworkModule#providesFacebookService
    Retrofit

    View Slide

  49. NetworkModule#providesRetrofit
    Retrofit
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit.create(InterfaceFacebookApi.class));
    }
    FacebookService NetworkModule#providesFacebookService

    View Slide

  50. NetworkModule#providesRetrofit
    Retrofit
    FacebookService NetworkModule#providesFacebookService
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit.create(InterfaceFacebookApi.class));
    }

    View Slide

  51. @Module public class NetworkModule {
    @Provides @Singleton Retrofit providesRetrofit() {
    return new Retrofit.Builder().build();
    }
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit.create(InterfaceFacebookApi.class));
    }
    }

    View Slide

  52. @Module public class NetworkModule {
    @Provides @Singleton OkHttpClient providesOkHttpClient() {
    return new OkHttpClient.Builder().build();
    }
    @Provides @Singleton Retrofit providesRetrofit(OkHttpClient okHttpClient) {
    return new Retrofit.Builder().client(okHttpClient)
    .build();
    }
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit.create(InterfaceFacebookApi.class));
    }
    }

    View Slide

  53. NetworkModule#providesRetrofit
    Retrofit
    NetworkModule#providesOkHttpClient
    OkHttpClient
    FacebookService NetworkModule#providesFacebookService

    View Slide

  54. [email protected](s) can be used together
    Dagger 2 API

    View Slide

  55. @Module public class FacebookModule {
    }

    View Slide

  56. @Module public class FacebookModule {
    @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService) {
    return new PostStatus(facebookService);
    }
    }

    View Slide

  57. NetworkModule#providesRetrofit
    Retrofit
    FacebookService NetworkModule#providesFacebookService
    PostStatus FacebookModule#providesPostStatus

    View Slide

  58. @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService) {
    return new PostStatus(facebookService);
    }
    NetworkModule#providesRetrofit
    Retrofit
    FacebookService NetworkModule#providesFacebookService
    PostStatus FacebookModule#providesPostStatus

    View Slide

  59. NetworkModule#providesRetrofit
    Retrofit
    FacebookService NetworkModule#providesFacebookService
    PostStatus FacebookModule#providesPostStatus
    @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService) {
    return new PostStatus(facebookService);
    }

    View Slide

  60. @Module public class FacebookModule {
    @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService) {
    return new PostStatus(facebookService);
    }
    }

    View Slide

  61. @Module public class FacebookModule {
    @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService) {
    return new PostStatus(facebookService);
    }
    @Provides @Singleton PostImage providesPostImage(FacebookService facebookService) {
    return new PostImage(facebookService);
    }
    }

    View Slide

  62. PostImage FacebookModule#providesPostImage
    NetworkModule#providesRetrofit
    Retrofit
    FacebookService NetworkModule#providesFacebookService
    PostStatus FacebookModule#providesPostStatus

    View Slide

  63. NetworkModule#providesRetrofit
    Retrofit
    FacebookService NetworkModule#providesFacebookService
    PostStatus FacebookModule#providesPostStatus
    PostImage FacebookModule#providesPostImage
    @Provides @Singleton PostImage providesPostImage(FacebookService facebookService) {
    return new PostImage(facebookService);
    }

    View Slide

  64. NetworkModule#providesRetrofit
    Retrofit
    FacebookService NetworkModule#providesFacebookService
    PostStatus FacebookModule#providesPostStatus
    PostImage FacebookModule#providesPostImage

    View Slide

  65. [email protected] requests dependencies
    -Constructor/Method/Field Injection
    Dagger 2 API

    View Slide

  66. [email protected] on one constructor
    -Constructor parameters = dependencies
    -Can store dependencies as immutable
    -Can use for downstream injection
    Constructor Injection

    View Slide

  67. @Module public class NetworkModule {
    @Provides @Singleton Retrofit providesRetrofit() {
    return new Retrofit.Builder().build();
    }
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit.create(InterfaceFacebookApi.class));
    }
    }

    View Slide

  68. @Module public class NetworkModule {
    @Provides @Singleton Retrofit providesRetrofit() {
    return new Retrofit.Builder().build();
    }
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit.create(InterfaceFacebookApi.class));
    }
    }

    View Slide

  69. public class FacebookService {
    private final InterfaceFacebookApi apiInterface;
    public FacebookService(InterfaceFacebookApi apiInterface) {
    this.apiInterface = apiInterface;
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }
    Constructor Injection

    View Slide

  70. public class FacebookService {
    private final InterfaceFacebookApi apiInterface;
    @Inject public FacebookService(Retrofit retrofit) {
    this.apiInterface = retrofit.create(InterfaceFacebookApi.class);
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }
    Constructor Injection

    View Slide

  71. @Singleton
    public class FacebookService {
    private final InterfaceFacebookApi apiInterface;
    @Inject public FacebookService(Retrofit retrofit) {
    this.apiInterface = retrofit.create(InterfaceFacebookApi.class);
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }
    Constructor Injection

    View Slide

  72. Method Injection
    [email protected] on methods
    -Method parameters = dependencies
    -Injection after object is fully instantiated
    -Use when you need to pass an instance of itself into
    dependency

    View Slide

  73. Method Injection
    public class MapActivity extends AppCompatActivity {
    @Inject void subscribeGPSChange(LocationCallback locationCallback) {
    locationCallback.subscribe(this);
    }
    }

    View Slide

  74. Field Injection
    [email protected] on fields
    -Fields = dependencies
    -Injection after object is fully instantiated
    -Risk of Mutability
    -Use in System objects

    View Slide

  75. Field Injection
    public class MainActivity extends AppCompatActivity {
    @Inject PostStatus postStatus;
    @Inject PostImage postImage;
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    //Inject here
    super.onCreate(savedInstanceState);
    }
    }

    View Slide

  76. [email protected] bridges @Inject and @Module/
    @Provide
    Dagger 2 API

    View Slide

  77. Components
    @Component
    public interface FacebookComponent {
    }

    View Slide

  78. Components
    @Component(modules = {
    NetworkModule.class,
    FacebookModule.class
    })
    public interface FacebookComponent {
    }

    View Slide

  79. Components
    @Component(modules = {
    NetworkModule.class,
    FacebookModule.class
    })
    public interface FacebookComponent {
    PostStatus postStatus();
    PostImage postImage();
    }

    View Slide

  80. Components
    @Singleton
    @Component(modules = {
    NetworkModule.class,
    FacebookModule.class
    })
    public interface FacebookComponent {
    PostStatus postStatus();
    PostImage postImage();
    }

    View Slide

  81. Retrofit retrofit = RetrofitProvider.get();
    FacebookService service = new FacebookService(retrofit);
    PostStatus postStatus = new PostStatus(service);
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");
    PostImage postImage = new PostImage(service);
    postImage.execute("www.example.com/boston.jpg");
    postImage.execute("www.example.com/paris.jpg");

    View Slide

  82. FacebookComponent facebookComponent = DaggerFacebookComponent.builder()
    .facebookModule(new FacebookModule())
    .networkModule(new NetworkModule())
    .build();
    PostStatus postStatus = facebookComponent.postStatus();
    postStatus.execute("Hello DevFest Yangon 2017");
    postStatus.execute("Nice to Meet you All");
    PostImage postImage = facebookComponent.postImage();
    postImage.execute("www.example.com/boston.jpg");
    postImage.execute("www.example.com/paris.jpg");

    View Slide

  83. class FacebookActivity extends AppCompatActivity {
    PostStatus postStatus;
    PostImage postImage;
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FacebookComponent facebookComponent = DaggerFacebookComponent.builder()
    .facebookModule(new FacebookModule())
    .networkModule(new NetworkModule())
    .build();
    this.postStatus = facebookComponent.postStatus();
    this.postImage = facebookComponent.postImage();
    }
    }

    View Slide

  84. Components
    @Component(modules = {
    NetworkModule.class,
    FacebookModule.class
    })
    public interface FacebookComponent {
    PostStatus postStatus();
    PostImage postImage();
    }

    View Slide

  85. Components
    @Singleton
    @Component(modules = {
    NetworkModule.class,
    FacebookModule.class
    })
    public interface FacebookComponent {
    void inject(Activity activity);
    }

    View Slide

  86. class FacebookActivity extends AppCompatActivity {
    PostStatus postStatus;
    PostImage postImage;
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FacebookComponent facebookComponent = DaggerFacebookComponent.builder()
    .facebookModule(new FacebookModule())
    .networkModule(new NetworkModule())
    .build();
    this.postStatus = facebookComponent.postStatus();
    this.postImage = facebookComponent.postImage();
    }
    }

    View Slide

  87. class FacebookActivity extends AppCompatActivity {
    @Inject PostStatus postStatus;
    @Inject PostImage postImage;
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DaggerFacebookComponent.builder()
    .facebookModule(new FacebookModule())
    .networkModule(new NetworkModule())
    .build()
    .inject(this);
    }
    }

    View Slide

  88. Scoping
    @Singleton
    @Component(modules = {
    NetworkModule.class,
    FacebookModule.class
    })
    public interface FacebookComponent {
    void inject(Activity activity);
    }

    View Slide

  89. Scoping
    @Singleton
    @Component(modules = {
    NetworkModule.class,
    FacebookModule.class
    })
    public interface FacebookComponent {
    void inject(Activity activity);
    }
    @Component(modules = {
    NetworkModule.class
    })
    @Singleton
    public class NetworkComponent {
    }

    View Slide

  90. @Singleton
    @Component(
    dependencies = { NetworkComponent.class },
    modules = { FacebookModule.class }
    )
    public interface FacebookComponent {
    void inject(Activity activity);
    }
    @Component(modules = {
    NetworkModule.class
    })
    @Singleton
    public class NetworkComponent {
    }
    Scoping

    View Slide

  91. @Singleton
    @Component(
    dependencies = { NetworkComponent.class },
    modules = { FacebookModule.class }
    )
    public interface FacebookComponent {
    void inject(Activity activity);
    }
    @Component(modules = {
    NetworkModule.class
    })
    @Singleton
    public interface NetworkComponent {
    FacebookService facebookService();
    }
    Scoping

    View Slide

  92. @Singleton
    @Component(
    dependencies = { NetworkComponent.class },
    modules = { FacebookModule.class }
    )
    public interface FacebookComponent {
    void inject(Activity activity);
    }
    @Component(modules = {
    NetworkModule.class
    })
    @Singleton
    public interface NetworkComponent {
    FacebookService facebookService();
    }
    Scoping

    View Slide

  93. @Component(
    dependencies = { NetworkComponent.class },
    modules = { FacebookModule.class }
    )
    public interface FacebookComponent {
    void inject(Activity activity);
    }
    @Component(modules = {
    NetworkModule.class
    })
    @Singleton
    public interface NetworkComponent {
    FacebookService facebookService();
    }
    Scoping

    View Slide

  94. @Component(
    dependencies = { NetworkComponent.class },
    modules = { FacebookModule.class }
    )
    public interface FacebookComponent {
    void inject(Activity activity);
    }
    @Module public class FacebookModule {
    @Provides @Singleton PostStatus providesPostStatus(FacebookService
    facebookService) {
    return new PostStatus(facebookService);
    }
    @Provides @Singleton PostImage providesPostImage(FacebookService
    facebookService) {
    return new PostImage(facebookService);
    }
    }
    Scoping

    View Slide

  95. @Component(
    dependencies = { NetworkComponent.class },
    modules = { FacebookModule.class }
    )
    public interface FacebookComponent {
    void inject(Activity activity);
    }
    @Module public class FacebookModule {
    @Provides PostStatus providesPostStatus(FacebookService facebookService) {
    return new PostStatus(facebookService);
    }
    @Provides PostImage providesPostImage(FacebookService facebookService) {
    return new PostImage(facebookService);
    }
    }
    Scoping

    View Slide

  96. Scoping
    @Scope
    public @interface StatusUpdateScreen {
    }

    View Slide

  97. Scoping
    @StatusUpdateScreen
    @Component(
    dependencies = { NetworkComponent.class },
    modules = { FacebookModule.class }
    )
    public interface FacebookComponent {
    void inject(Activity activity);
    }

    View Slide

  98. Scoping
    @Module public class FacebookModule {
    @Provides PostStatus providesPostStatus(FacebookService facebookService) {
    return new PostStatus(facebookService);
    }
    @Provides PostImage providesPostImage(FacebookService facebookService) {
    return new PostImage(facebookService);
    }
    }

    View Slide

  99. Scoping
    @Module public class FacebookModule {
    @Provides @StatusUpdateScreen PostStatus providesPostStatus(FacebookService
    facebookService) {
    return new PostStatus(facebookService);
    }
    @Provides @StatusUpdateScreen PostImage providesPostImage(FacebookService
    facebookService) {
    return new PostImage(facebookService);
    }
    }

    View Slide

  100. Scoping
    class StatusUpdateActivity extends AppCompatActivity {
    @Inject PostStatus postStatus;
    @Inject PostImage postImage;
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    NetworkComponent daggerNetworkComponent = DaggerNetworkComponent.create();
    DaggerStatusUpdateComponent.builder()
    .networkComponent(daggerNetworkComponent)
    .facebookModule(new FacebookModule())
    .build()
    .inject(this);
    }
    }

    View Slide

  101. Network Component

    View Slide

  102. Network Component
    Network
    Module
    Retrofit
    Facebook
    Service

    View Slide

  103. Network Component
    Network
    Module
    Retrofit
    Facebook
    Service
    Facebook
    Service

    View Slide

  104. Network Component
    Network
    Module
    Retrofit
    Facebook
    Service
    Facebook
    Service
    Post
    Status Component

    View Slide

  105. Network Component
    Network
    Module
    Retrofit
    Facebook
    Service
    Facebook
    Service
    Post
    Status Component
    FacebookModule
    PostStatus
    PostImage

    View Slide

  106. Network Component
    Network
    Module
    Retrofit
    Facebook
    Service
    Facebook
    Service

    View Slide

  107. Generated Code Under The Hood
    @Module public class NetworkModule {
    @Provides @Singleton OkHttpClient providesOkHttpClient() {
    return new OkHttpClient.Builder().build();
    }
    @Provides @Singleton Retrofit providesRetrofit(OkHttpClient okHttpClient) {
    return new Retrofit.Builder().client(okHttpClient)
    .build();
    }
    @Provides @Singleton FacebookService providesFaceookService(Retrofit retrofit) {
    return new FacebookService(retrofit);
    }
    }

    View Slide

  108. Generated Code Under The Hood
    @Module public class NetworkModule {
    @Provides @Singleton OkHttpClient providesOkHttpClient() {
    return new OkHttpClient.Builder().build();
    }
    @Provides @Singleton Retrofit providesRetrofit(OkHttpClient okHttpClient) {
    return new Retrofit.Builder().client(okHttpClient)
    .build();
    }
    @Provides @Singleton FacebookService providesFaceookService(Retrofit retrofit) {
    return new FacebookService(retrofit);
    }
    }

    View Slide

  109. Generated Code Under The Hood
    public final class NetworkModule_ProvidesOkHttpClientFactory implements
    Factory {
    private final NetworkModule module;
    public NetworkModule_ProvidesOkHttpClientFactory(NetworkModule module) {
    assert module != null;
    this.module = module;
    }
    @Override public OkHttpClient get() {
    return Preconditions.checkNotNull(module.providesOkHttpClient(),
    "Cannot return null from a [email protected] @Provides method");
    }
    public static Factory create(NetworkModule module) {
    return new NetworkModule_ProvidesOkHttpClientFactory(module);
    }
    }

    View Slide

  110. Generated Code Under The Hood
    public final class NetworkModule_ProvidesOkHttpClientFactory implements
    Factory {
    private final NetworkModule module;
    public NetworkModule_ProvidesOkHttpClientFactory(NetworkModule module) {
    assert module != null;
    this.module = module;
    }
    @Override public OkHttpClient get() {
    return Preconditions.checkNotNull(module.providesOkHttpClient(),
    "Cannot return null from a [email protected] @Provides method");
    }
    public static Factory create(NetworkModule module) {
    return new NetworkModule_ProvidesOkHttpClientFactory(module);
    }
    }

    View Slide

  111. Generated Code Under The Hood
    public final class NetworkModule_ProvidesOkHttpClientFactory implements
    Factory {
    private final NetworkModule module;
    public NetworkModule_ProvidesOkHttpClientFactory(NetworkModule module) {
    assert module != null;
    this.module = module;
    }
    @Override public OkHttpClient get() {
    return Preconditions.checkNotNull(module.providesOkHttpClient(),
    "Cannot return null from a [email protected] @Provides method");
    }
    public static Factory create(NetworkModule module) {
    return new NetworkModule_ProvidesOkHttpClientFactory(module);
    }
    }

    View Slide

  112. Generated Code Under The Hood
    public final class NetworkModule_ProvidesRetrofitFactory implements
    Factory {
    private final NetworkModule module;
    private final Provider okHttpClientProvider;
    public NetworkModule_ProvidesRetrofitFactory(
    NetworkModule module, Provider okHttpClientProvider) {
    assert module != null;
    this.module = module;
    assert okHttpClientProvider != null;
    this.okHttpClientProvider = okHttpClientProvider;
    }
    @Override
    public Retrofit get() {
    return Preconditions.checkNotNull(
    module.providesRetrofit(okHttpClientProvider.get()),
    "Cannot return null from a [email protected] @Provides method");
    }
    public static Factory create(
    NetworkModule module, Provider okHttpClientProvider) {
    return new NetworkModule_ProvidesRetrofitFactory(module, okHttpClientProvider);
    }
    }

    View Slide

  113. Generated Code Under The Hood
    public final class NetworkModule_ProvidesRetrofitFactory implements
    Factory {
    private final NetworkModule module;
    private final Provider okHttpClientProvider;
    public NetworkModule_ProvidesRetrofitFactory(
    NetworkModule module, Provider okHttpClientProvider) {
    assert module != null;
    this.module = module;
    assert okHttpClientProvider != null;
    this.okHttpClientProvider = okHttpClientProvider;
    }
    @Override
    public Retrofit get() {
    return Preconditions.checkNotNull(
    module.providesRetrofit(okHttpClientProvider.get()),
    "Cannot return null from a [email protected] @Provides method");
    }
    public static Factory create(
    NetworkModule module, Provider okHttpClientProvider) {
    return new NetworkModule_ProvidesRetrofitFactory(module, okHttpClientProvider);
    }
    }

    View Slide

  114. Generated Code Under The Hood
    public final class NetworkModule_ProvidesRetrofitFactory implements
    Factory {
    private final NetworkModule module;
    private final Provider okHttpClientProvider;
    public NetworkModule_ProvidesRetrofitFactory(
    NetworkModule module, Provider okHttpClientProvider) {
    assert module != null;
    this.module = module;
    assert okHttpClientProvider != null;
    this.okHttpClientProvider = okHttpClientProvider;
    }
    @Override
    public Retrofit get() {
    return Preconditions.checkNotNull(
    module.providesRetrofit(okHttpClientProvider.get()),
    "Cannot return null from a [email protected] @Provides method");
    }
    public static Factory create(
    NetworkModule module, Provider okHttpClientProvider) {
    return new NetworkModule_ProvidesRetrofitFactory(module, okHttpClientProvider);
    }
    }

    View Slide

  115. Generated Code Under The Hood
    public final class DaggerNetworkComponent implements NetworkComponent {
    private Provider providesOkHttpClientProvider;
    private Provider providesRetrofitProvider;
    private Provider providesFaceookServiceProvider;
    private DaggerNetworkComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
    }
    public static Builder builder() {
    return new Builder();
    }
    public static NetworkComponent create() {
    return new Builder().build();
    }
    @SuppressWarnings("unchecked")
    private void initialize(final Builder builder) {
    this.providesOkHttpClientProvider =
    DoubleCheck.provider(
    NetworkModule_ProvidesOkHttpClientFactory.create(builder.networkModule));
    this.providesRetrofitProvider =
    DoubleCheck.provider(
    NetworkModule_ProvidesRetrofitFactory.create(
    builder.networkModule, providesOkHttpClientProvider));
    this.providesFaceookServiceProvider =
    DoubleCheck.provider(
    NetworkModule_ProvidesFaceookServiceFactory.create(
    builder.networkModule, providesRetrofitProvider));
    }
    @Override
    public FacebookService facebookService() {
    return providesFaceookServiceProvider.get();
    }
    }

    View Slide

  116. Generated Code Under The Hood
    private void initialize(final Builder builder) {
    this.providesOkHttpClientProvider =
    NetworkModule_ProvidesOkHttpClientFactory.create(builder.networkModule);
    this.providesRetrofitProvider =
    NetworkModule_ProvidesRetrofitFactory.create(
    builder.networkModule, providesOkHttpClientProvider);
    this.providesFacebookServiceProvider =
    NetworkModule_ProvidesFacebookServiceFactory.create(
    builder.networkModule, providesRetrofitProvider);
    }

    View Slide

  117. Generated Code Under The Hood
    private void initialize(final Builder builder) {
    this.providesOkHttpClientProvider =
    NetworkModule_ProvidesOkHttpClientFactory.create(builder.networkModule);
    this.providesRetrofitProvider =
    NetworkModule_ProvidesRetrofitFactory.create(
    builder.networkModule, providesOkHttpClientProvider);
    this.providesFacebookServiceProvider =
    NetworkModule_ProvidesFacebookServiceFactory.create(
    builder.networkModule, providesRetrofitProvider);
    }
    @Override
    public FacebookService facebookService() {
    return providesFacebookServiceProvider();
    }

    View Slide

  118. Generated Code Under The Hood
    class StatusUpdateActivity extends AppCompatActivity {
    @Inject PostStatus postStatus;
    @Inject PostImage postImage;
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    NetworkComponent daggerNetworkComponent = DaggerNetworkComponent.create();
    DaggerStatusUpdateComponent.builder()
    .networkComponent(daggerNetworkComponent)
    .facebookModule(new FacebookModule())
    .build()
    .inject(this);
    }
    }

    View Slide

  119. Generated Code Under The Hood
    public final class StatusUpdateActivity_MembersInjector
    implements MembersInjector {
    private final Provider postStatusProvider;
    private final Provider postImageProvider;
    public StatusUpdateActivity_MembersInjector(
    Provider postStatusProvider, Provider postImageProvider) {
    assert postStatusProvider != null;
    this.postStatusProvider = postStatusProvider;
    assert postImageProvider != null;
    this.postImageProvider = postImageProvider;
    }
    public static MembersInjector create(
    Provider postStatusProvider, Provider postImageProvider) {
    return new StatusUpdateActivity_MembersInjector(postStatusProvider, postImageProvider);
    }
    @Override
    public void injectMembers(StatusUpdateActivity instance) {
    if (instance == null) {
    throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.postStatus = postStatusProvider.get();
    instance.postImage = postImageProvider.get();
    }
    public static void injectPostStatus(
    StatusUpdateActivity instance, Provider postStatusProvider) {
    instance.postStatus = postStatusProvider.get();
    }
    public static void injectPostImage(
    StatusUpdateActivity instance, Provider postImageProvider) {
    instance.postImage = postImageProvider.get();
    }
    }

    View Slide

  120. Generated Code Under The Hood
    public void injectMembers(StatusUpdateActivity instance) {
    if (instance == null) {
    throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.postStatus = postStatusProvider.get();
    instance.postImage = postImageProvider.get();
    }

    View Slide

  121. General Rules of Thumbs

    View Slide

  122. Favour Constructor Injection

    View Slide

  123. Favour Constructor Injection
    public class FacebookService {
    @Inject private InterfaceFacebookApi apiInterface;
    public FacebookService() {
    //Inject here
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    }

    View Slide

  124. Favour Constructor Injection
    public class FacebookService {
    @Inject private InterfaceFacebookApi apiInterface;
    private DbFacebook dbFacbook;
    public FacebookService() {
    //Inject here
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    //Save on fail
    }
    public void saveStatus(String status) {
    dbFacbook.saveStatus(status);
    }
    }

    View Slide

  125. Favour Constructor Injection
    public class FacebookService {
    @Inject private InterfaceFacebookApi apiInterface;
    private DbFacebook dbFacbook;
    public FacebookService() {
    //Inject here
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    //Save on fail
    }
    public void saveStatus(String status) {
    //NULL POINTER EXECPTION
    dbFacbook.saveStatus(status);
    }
    }

    View Slide

  126. Favour Constructor Injection
    public class FacebookService {
    @Inject private InterfaceFacebookApi apiInterface;
    @Inject private DbFacebook dbFacbook;
    public FacebookService() {
    //Inject here
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    //Save on fail
    }
    public void saveStatus(String status) {
    dbFacbook.saveStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }

    View Slide

  127. Favour Constructor Injection
    public class FacebookService {
    private final InterfaceFacebookApi apiInterface;
    private final DbFacebook dbFacbook;
    public FacebookService() {
    //Inject here
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    //Save on fail
    }
    public void saveStatus(String status) {
    dbFacbook.saveStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }

    View Slide

  128. Favour Constructor Injection

    View Slide

  129. Favour Constructor Injection

    View Slide

  130. Favour Constructor Injection
    public class FacebookService {
    private final InterfaceFacebookApi apiInterface;
    private final DbFacebook dbFacbook;
    @Inject public FacebookService(InterfaceFacebookApi apiInterface,
    DbFacebook dbFacbook) {
    this.apiInterface = apiInterface;
    this.dbFacbook = dbFacbook;
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    //Save on fail
    }
    public void saveStatus(String status) {
    dbFacbook.saveStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }

    View Slide

  131. Favour Constructor Injection
    class StatusUpdateActivity extends AppCompatActivity {
    @Inject PostStatus postStatus;
    @Inject PostImage postImage;
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    NetworkComponent daggerNetworkComponent = DaggerNetworkComponent.create();
    DaggerStatusUpdateComponent.builder()
    .networkComponent(daggerNetworkComponent)
    .facebookModule(new FacebookModule())
    .build()
    .inject(this);
    }
    }

    View Slide

  132. Don’t use Singleton everywhere
    -Use Singleton only when the state is mutable
    -Don’t use if there’s no mutable object
    -Use if expensive

    View Slide

  133. Don’t use Singleton everywhere
    -Use Singleton only when the state is mutable
    @Singleton
    public class DbConnectionCounter {
    public Integer connectionCount = 0;
    @Inject public DbConnectionCounter(Context context) {
    //Implementation
    }
    void increment() {
    connectionCount = connectionCount++;
    }
    void decerement() {
    if (connectionCount > 0) {
    connectionCount = connectionCount--;
    }
    }
    }

    View Slide

  134. Don’t use Singleton everywhere
    -Immutable, don’t use
    public class PostStatus {
    private final FacebookService service;
    @Inject public PostStatus(FacebookService service) {
    this.service = service;
    }
    public void execute(String status) {
    service.postStatus(status);
    }
    }

    View Slide

  135. Don’t use Singleton everywhere
    -Use if the object is expensive to create
    @Module public class NetworkModule {
    @Provides @Singleton OkHttpClient providesOkHttpClient() {
    return new OkHttpClient.Builder().build();
    }
    @Provides @Singleton Retrofit providesRetrofit(OkHttpClient okHttpClient) {
    return new Retrofit.Builder().client(okHttpClient).build();
    }
    }

    View Slide

  136. Use @Inject when you can
    @Module public class NetworkModule {
    @Provides @Singleton OkHttpClient providesOkHttpClient() {
    return new OkHttpClient.Builder().build();
    }
    @Provides @Singleton Retrofit providesRetrofit(OkHttpClient okHttpClient) {
    return new Retrofit.Builder().client(okHttpClient).build();
    }
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit);
    }
    }

    View Slide

  137. Use @Inject when you can
    @Module public class NetworkModule {
    @Provides @Singleton OkHttpClient providesOkHttpClient() {
    return new OkHttpClient.Builder().build();
    }
    @Provides @Singleton Retrofit providesRetrofit(OkHttpClient okHttpClient) {
    return new Retrofit.Builder().client(okHttpClient).build();
    }
    @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) {
    return new FacebookService(retrofit);
    }
    }

    View Slide

  138. Use @Inject when you can
    public class FacebookService {
    private final InterfaceFacebookApi apiInterface;
    @Inject public FacebookService(Retrofit retrofit) {
    this.apiInterface = retrofit.create(InterfaceFacebookApi.class);
    }
    public void postStatus(String status) {
    apiInterface.postStatus(status);
    }
    public void postImage(String imageLink) {
    apiInterface.postImage(imageLink);
    }
    }

    View Slide

  139. Use static @Provides Methods
    @Module public class AppModule {
    @Provides ErrorMessageFactory errorMessageFactory() {
    return new ErrorMessageFactory();
    }
    }
    @Component(modules = AppModule.class)
    public interface AppComponent {
    ErrorMessageFactory errorMessageFactory();
    }

    View Slide

  140. Use static @Provides Methods
    public final class DaggerAppComponent implements AppComponent {
    private Provider errorMessageFactoryProvider;
    //...
    @Override public ErrorMessageFactory errorMessageFactory() {
    return errorMessageFactoryProvider.get();
    }
    //...
    }

    View Slide

  141. Use static @Provides Methods
    @Module public class AppModule {
    @Provides ErrorMessageFactory errorMessageFactory() {
    return new ErrorMessageFactory();
    }
    }
    @Component(modules = AppModule.class)
    public interface AppComponent {
    ErrorMessageFactory errorMessageFactory();
    }

    View Slide

  142. Use static @Provides Methods
    @Module public class AppModule {
    @Provides static ErrorMessageFactory errorMessageFactory() {
    return new ErrorMessageFactory();
    }
    }
    @Component(modules = AppModule.class)
    public interface AppComponent {
    ErrorMessageFactory errorMessageFactory();
    }

    View Slide

  143. Use static @Provides Methods
    public final class DaggerAppComponent implements AppComponent {
    //...
    @Override
    public ErrorMessageFactory errorMessageFactory() {
    return AppModule.errorMessageFactory();
    }
    //...
    }

    View Slide

  144. Use static @Provides Methods
    @Module public class AppModule {
    @Provides static ErrorMessageFactory errorMessageFactory() {
    return new ErrorMessageFactory();
    }
    }

    View Slide

  145. Use static @Provides Methods
    @Module public abstract class AppModule {
    @Provides static ErrorMessageFactory errorMessageFactory() {
    return new ErrorMessageFactory();
    }
    }

    View Slide

  146. Avoid @Singleton on providing abstractions
    @Provides @Singleton
    NetworkManager provideNetworkManager(NetworkManagerImpl networkManagerImpl) {
    return networkManagerImpl;
    }

    View Slide

  147. Avoid @Singleton on providing abstractions
    @Provides
    NetworkManager provideNetworkManager(NetworkManagerImpl networkManagerImpl) {
    return networkManagerImpl;
    }
    @Singleton
    public class NetworkManagerImpl implements NetworkManager
    {
    }

    View Slide

  148. Don’t Stress on scoping

    View Slide

  149. Q & A

    View Slide