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)

0991ca4bc363163337f7b02b98af538a?s=128

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

  2. Dependency? public class A { B b; public A() {

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

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

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

    this.b = b; } } Injected into A B
  6. S.O.L.I.D Principle • Single Responsibility Principle • Open/Closed Principle •

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

    Liskov Substitution Principle • Interface Segregation Principle • Dependency Inversion Principle
  8. Dependency Inversion Principle • Depend on abstractions. Do not depend

    on concretions.
  9. Network Abstraction Retrofit Volley Mock App

  10. Dependency Injection -A pattern

  11. public class FacebookService { public void postStatus(String status) { InterfaceFacebookApi

    apiInterface= RetrofitProvider.createFacebookApi(); apiInterface.postStatus(status); } }
  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); } }
  13. PostStatus postStatus = new PostStatus(); postStatus.execute("Hello DevFest Yangon 2017"); postStatus.execute("Nice

    to Meet you All");
  14. public class FacebookService { public void postStatus(String status) { InterfaceFacebookApi

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

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

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

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

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

    void execute(String status) { service.postStatus(status); } }
  20. PostStatus postStatus = new PostStatus(); postStatus.execute("Hello DevFest Yangon 2017"); postStatus.execute("Nice

    to Meet you All");
  21. PostStatus Facebook Service Retrofit

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

    to Meet you All");
  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");
  24. public class FacebookService { InterfaceFacebookApi apiInterface; public FacebookService(InterfaceFacebookApi apiInterface) {

    this.apiInterface = apiInterface; } public void postStatus(String status) { apiInterface.postStatus(status); } }
  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); } }
  26. public class PostImage { FacebookService service = new FacebookService(RetrofitProvider.createFacebookApi()); public

    void execute(String imageUrl) { service.postImage(imageUrl); } }
  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); } }
  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); } }
  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); } }
  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");
  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");
  32. PostStatus Facebook Service Retrofit

  33. PostStatus Facebook Service Retrofit PostImage

  34. DI comes at the cost of boilerplate

  35. Spring DI Framework

  36. - Developed by Pivotal Software - Written in XML -

    Runtime crashes - Untraceable Spring
  37. Spring Guice DI Framework

  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
  39. DI Framework Spring Guice Dagger 1

  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
  41. DI Framework Spring Guice Dagger 1 Dagger 2

  42. - Developed by Java Core Lib Team - Written with

    Java - Compile time crashes - Eliminated overheads - Support Scoping Dagger 2
  43. Dagger 2 API @Module / @Provides - Provide dependencies

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

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

    - Request dependencies @Component - Bridge modules and injections
  46. -@Module is a class that holds related dependencies -@Provides is

    the method of module classes Dagger 2 API
  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)); } }
  48. FacebookService NetworkModule#providesRetrofit NetworkModule#providesFacebookService Retrofit

  49. NetworkModule#providesRetrofit Retrofit @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) { return new

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

    return new FacebookService(retrofit.create(InterfaceFacebookApi.class)); }
  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)); } }
  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)); } }
  53. NetworkModule#providesRetrofit Retrofit NetworkModule#providesOkHttpClient OkHttpClient FacebookService NetworkModule#providesFacebookService

  54. -@Module(s) can be used together Dagger 2 API

  55. @Module public class FacebookModule { }

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

    { return new PostStatus(facebookService); } }
  57. NetworkModule#providesRetrofit Retrofit FacebookService NetworkModule#providesFacebookService PostStatus FacebookModule#providesPostStatus

  58. @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService) { return new PostStatus(facebookService); }

    NetworkModule#providesRetrofit Retrofit FacebookService NetworkModule#providesFacebookService PostStatus FacebookModule#providesPostStatus
  59. NetworkModule#providesRetrofit Retrofit FacebookService NetworkModule#providesFacebookService PostStatus FacebookModule#providesPostStatus @Provides @Singleton PostStatus providesPostStatus(FacebookService

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

    { return new PostStatus(facebookService); } }
  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); } }
  62. PostImage FacebookModule#providesPostImage NetworkModule#providesRetrofit Retrofit FacebookService NetworkModule#providesFacebookService PostStatus FacebookModule#providesPostStatus

  63. NetworkModule#providesRetrofit Retrofit FacebookService NetworkModule#providesFacebookService PostStatus FacebookModule#providesPostStatus PostImage FacebookModule#providesPostImage @Provides @Singleton

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

  65. -@Inject requests dependencies -Constructor/Method/Field Injection Dagger 2 API

  66. -@Inject on one constructor -Constructor parameters = dependencies -Can store

    dependencies as immutable -Can use for downstream injection Constructor Injection
  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)); } }
  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)); } }
  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
  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
  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
  72. Method Injection -@Inject on methods -Method parameters = dependencies -Injection

    after object is fully instantiated -Use when you need to pass an instance of itself into dependency
  73. Method Injection public class MapActivity extends AppCompatActivity { @Inject void

    subscribeGPSChange(LocationCallback locationCallback) { locationCallback.subscribe(this); } }
  74. Field Injection -@Inject on fields -Fields = dependencies -Injection after

    object is fully instantiated -Risk of Mutability -Use in System objects
  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); } }
  76. -@Components bridges @Inject and @Module/ @Provide Dagger 2 API

  77. Components @Component public interface FacebookComponent { }

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

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

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

    FacebookComponent { PostStatus postStatus(); PostImage postImage(); }
  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");
  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");
  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(); } }
  84. Components @Component(modules = { NetworkModule.class, FacebookModule.class }) public interface FacebookComponent

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

    FacebookComponent { void inject(Activity activity); }
  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(); } }
  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); } }
  88. Scoping @Singleton @Component(modules = { NetworkModule.class, FacebookModule.class }) public interface

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

    FacebookComponent { void inject(Activity activity); } @Component(modules = { NetworkModule.class }) @Singleton public class NetworkComponent { }
  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
  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
  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
  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
  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
  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
  96. Scoping @Scope public @interface StatusUpdateScreen { }

  97. Scoping @StatusUpdateScreen @Component( dependencies = { NetworkComponent.class }, modules =

    { FacebookModule.class } ) public interface FacebookComponent { void inject(Activity activity); }
  98. Scoping @Module public class FacebookModule { @Provides PostStatus providesPostStatus(FacebookService facebookService)

    { return new PostStatus(facebookService); } @Provides PostImage providesPostImage(FacebookService facebookService) { return new PostImage(facebookService); } }
  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); } }
  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); } }
  101. Network Component

  102. Network Component Network Module Retrofit Facebook Service

  103. Network Component Network Module Retrofit Facebook Service Facebook Service

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

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

    Status Component FacebookModule PostStatus PostImage
  106. Network Component Network Module Retrofit Facebook Service Facebook Service

  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); } }
  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); } }
  109. Generated Code Under The Hood public final class NetworkModule_ProvidesOkHttpClientFactory implements

    Factory<OkHttpClient> { 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 non-@Nullable @Provides method"); } public static Factory<OkHttpClient> create(NetworkModule module) { return new NetworkModule_ProvidesOkHttpClientFactory(module); } }
  110. Generated Code Under The Hood public final class NetworkModule_ProvidesOkHttpClientFactory implements

    Factory<OkHttpClient> { 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 non-@Nullable @Provides method"); } public static Factory<OkHttpClient> create(NetworkModule module) { return new NetworkModule_ProvidesOkHttpClientFactory(module); } }
  111. Generated Code Under The Hood public final class NetworkModule_ProvidesOkHttpClientFactory implements

    Factory<OkHttpClient> { 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 non-@Nullable @Provides method"); } public static Factory<OkHttpClient> create(NetworkModule module) { return new NetworkModule_ProvidesOkHttpClientFactory(module); } }
  112. Generated Code Under The Hood public final class NetworkModule_ProvidesRetrofitFactory implements

    Factory<Retrofit> { private final NetworkModule module; private final Provider<OkHttpClient> okHttpClientProvider; public NetworkModule_ProvidesRetrofitFactory( NetworkModule module, Provider<OkHttpClient> 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 non-@Nullable @Provides method"); } public static Factory<Retrofit> create( NetworkModule module, Provider<OkHttpClient> okHttpClientProvider) { return new NetworkModule_ProvidesRetrofitFactory(module, okHttpClientProvider); } }
  113. Generated Code Under The Hood public final class NetworkModule_ProvidesRetrofitFactory implements

    Factory<Retrofit> { private final NetworkModule module; private final Provider<OkHttpClient> okHttpClientProvider; public NetworkModule_ProvidesRetrofitFactory( NetworkModule module, Provider<OkHttpClient> 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 non-@Nullable @Provides method"); } public static Factory<Retrofit> create( NetworkModule module, Provider<OkHttpClient> okHttpClientProvider) { return new NetworkModule_ProvidesRetrofitFactory(module, okHttpClientProvider); } }
  114. Generated Code Under The Hood public final class NetworkModule_ProvidesRetrofitFactory implements

    Factory<Retrofit> { private final NetworkModule module; private final Provider<OkHttpClient> okHttpClientProvider; public NetworkModule_ProvidesRetrofitFactory( NetworkModule module, Provider<OkHttpClient> 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 non-@Nullable @Provides method"); } public static Factory<Retrofit> create( NetworkModule module, Provider<OkHttpClient> okHttpClientProvider) { return new NetworkModule_ProvidesRetrofitFactory(module, okHttpClientProvider); } }
  115. Generated Code Under The Hood public final class DaggerNetworkComponent implements

    NetworkComponent { private Provider<OkHttpClient> providesOkHttpClientProvider; private Provider<Retrofit> providesRetrofitProvider; private Provider<FacebookService> 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(); } }
  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); }
  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(); }
  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); } }
  119. Generated Code Under The Hood public final class StatusUpdateActivity_MembersInjector implements

    MembersInjector<StatusUpdateActivity> { private final Provider<PostStatus> postStatusProvider; private final Provider<PostImage> postImageProvider; public StatusUpdateActivity_MembersInjector( Provider<PostStatus> postStatusProvider, Provider<PostImage> postImageProvider) { assert postStatusProvider != null; this.postStatusProvider = postStatusProvider; assert postImageProvider != null; this.postImageProvider = postImageProvider; } public static MembersInjector<StatusUpdateActivity> create( Provider<PostStatus> postStatusProvider, Provider<PostImage> 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<PostStatus> postStatusProvider) { instance.postStatus = postStatusProvider.get(); } public static void injectPostImage( StatusUpdateActivity instance, Provider<PostImage> postImageProvider) { instance.postImage = postImageProvider.get(); } }
  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(); }
  121. General Rules of Thumbs

  122. Favour Constructor Injection

  123. Favour Constructor Injection public class FacebookService { @Inject private InterfaceFacebookApi

    apiInterface; public FacebookService() { //Inject here } public void postStatus(String status) { apiInterface.postStatus(status); } }
  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); } }
  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); } }
  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); } }
  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); } }
  128. Favour Constructor Injection

  129. Favour Constructor Injection

  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); } }
  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); } }
  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
  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--; } } }
  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); } }
  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(); } }
  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); } }
  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); } }
  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); } }
  139. Use static @Provides Methods @Module public class AppModule { @Provides

    ErrorMessageFactory errorMessageFactory() { return new ErrorMessageFactory(); } } @Component(modules = AppModule.class) public interface AppComponent { ErrorMessageFactory errorMessageFactory(); }
  140. Use static @Provides Methods public final class DaggerAppComponent implements AppComponent

    { private Provider<ErrorMessageFactory> errorMessageFactoryProvider; //... @Override public ErrorMessageFactory errorMessageFactory() { return errorMessageFactoryProvider.get(); } //... }
  141. Use static @Provides Methods @Module public class AppModule { @Provides

    ErrorMessageFactory errorMessageFactory() { return new ErrorMessageFactory(); } } @Component(modules = AppModule.class) public interface AppComponent { ErrorMessageFactory errorMessageFactory(); }
  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(); }
  143. Use static @Provides Methods public final class DaggerAppComponent implements AppComponent

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

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

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

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

    return networkManagerImpl; } @Singleton public class NetworkManagerImpl implements NetworkManager { }
  148. Don’t Stress on scoping

  149. Q & A