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. creates public class A { B b; public A() {

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

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

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

    Liskov Substitution Principle • Interface Segregation Principle • Dependency Inversion Principle
  5. public class FacebookService { public void postStatus(String status) { InterfaceFacebookApi

    apiInterface= RetrofitProvider.createFacebookApi(); apiInterface.postStatus(status); } }
  6. 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); } }
  7. public class FacebookService { public void postStatus(String status) { InterfaceFacebookApi

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

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

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

    service = new FacebookService(RetrofitProvider.createFacebookApi()); service.postStatus(status); } }
  11. 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");
  12. public class FacebookService { InterfaceFacebookApi apiInterface; public FacebookService(InterfaceFacebookApi apiInterface) {

    this.apiInterface = apiInterface; } public void postStatus(String status) { apiInterface.postStatus(status); } }
  13. 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); } }
  14. 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); } }
  15. 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); } }
  16. 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); } }
  17. 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");
  18. 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");
  19. - Developed by Pivotal Software - Written in XML -

    Runtime crashes - Untraceable Spring
  20. - 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
  21. - 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
  22. - Developed by Java Core Lib Team - Written with

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

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

    the method of module classes Dagger 2 API
  25. @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)); } }
  26. NetworkModule#providesRetrofit Retrofit @Provides @Singleton FacebookService providesFacebookService(Retrofit retrofit) { return new

    FacebookService(retrofit.create(InterfaceFacebookApi.class)); } FacebookService NetworkModule#providesFacebookService
  27. @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)); } }
  28. @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)); } }
  29. @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService) { return new PostStatus(facebookService); }

    NetworkModule#providesRetrofit Retrofit FacebookService NetworkModule#providesFacebookService PostStatus FacebookModule#providesPostStatus
  30. @Module public class FacebookModule { @Provides @Singleton PostStatus providesPostStatus(FacebookService facebookService)

    { return new PostStatus(facebookService); } @Provides @Singleton PostImage providesPostImage(FacebookService facebookService) { return new PostImage(facebookService); } }
  31. -@Inject on one constructor -Constructor parameters = dependencies -Can store

    dependencies as immutable -Can use for downstream injection Constructor Injection
  32. @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)); } }
  33. @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)); } }
  34. 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
  35. 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
  36. @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
  37. 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
  38. Method Injection public class MapActivity extends AppCompatActivity { @Inject void

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

    object is fully instantiated -Risk of Mutability -Use in System objects
  40. 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); } }
  41. Components @Singleton @Component(modules = { NetworkModule.class, FacebookModule.class }) public interface

    FacebookComponent { PostStatus postStatus(); PostImage postImage(); }
  42. 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");
  43. 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");
  44. 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(); } }
  45. 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(); } }
  46. 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); } }
  47. Scoping @Singleton @Component(modules = { NetworkModule.class, FacebookModule.class }) public interface

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

    FacebookModule.class } ) public interface FacebookComponent { void inject(Activity activity); } @Component(modules = { NetworkModule.class }) @Singleton public class NetworkComponent { } Scoping
  49. @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
  50. @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
  51. @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
  52. @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
  53. @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
  54. Scoping @StatusUpdateScreen @Component( dependencies = { NetworkComponent.class }, modules =

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

    { return new PostStatus(facebookService); } @Provides PostImage providesPostImage(FacebookService facebookService) { return new PostImage(facebookService); } }
  56. 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); } }
  57. 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); } }
  58. Network Component Network Module Retrofit Facebook Service Facebook Service Post

    Status Component FacebookModule PostStatus PostImage
  59. 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); } }
  60. 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); } }
  61. 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); } }
  62. 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); } }
  63. 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); } }
  64. 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); } }
  65. 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); } }
  66. 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); } }
  67. 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(); } }
  68. 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); }
  69. 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(); }
  70. 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); } }
  71. 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(); } }
  72. 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(); }
  73. Favour Constructor Injection public class FacebookService { @Inject private InterfaceFacebookApi

    apiInterface; public FacebookService() { //Inject here } public void postStatus(String status) { apiInterface.postStatus(status); } }
  74. 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); } }
  75. 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); } }
  76. 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); } }
  77. 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); } }
  78. 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); } }
  79. 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); } }
  80. 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
  81. 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--; } } }
  82. 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); } }
  83. 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(); } }
  84. 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); } }
  85. 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); } }
  86. 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); } }
  87. Use static @Provides Methods @Module public class AppModule { @Provides

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

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

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

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

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

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

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

    return networkManagerImpl; } @Singleton public class NetworkManagerImpl implements NetworkManager { }