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

Dependency Injection in Android using Dagger 2

Dependency Injection in Android using Dagger 2

Presentation for the talk Dependency Injection in Android using Dagger 2 given in Droidcon india https://droidcon.in/2015/

Gaurav Vashisth

December 17, 2015
Tweet

Other Decks in Programming

Transcript

  1. No Dependency Injection public class ClientClass {
 
 private DependencyClass

    dependency;
 
 // Specifying a specific implementation in the constructor
 public ClientClass() {
 dependency = new DependencyClass();
 }
 
 …
 
 } public class MyInjector {
 public static void main(String[] args) {
 ClientClass clientClass = new ClientClass();
 …
 }
 }
  2. No Dependency Injection • WHAT HAPPENS WHEN CONSTRUCTOR OF DEPENDENCY

    CHANGE? • YOU WOULD HAVE TO REFACTOR CLIENT’S CODE TOO • WHAT IF YOU WANT HAVE A SINGLE INSTANCE OF DEPENDENCY IN ALL CLIENTS?
  3. No Dependency Injection public class ClientClass {
 
 private DependencyClass

    dependency;
 
 // Specifying a specific implementation in the constructor
 public ClientClass() {
 dependency = new DependencyClass(new DependencyTwo());
 }
 
 … 
 } public class MyInjector {
 public static void main(String[] args) {
 ClientClass clientClass = new ClientClass();
 …
 }
 }
  4. No Dependency Injection • WHAT HAPPENS WHEN CONSTRUCTOR OF DEPENDENCY

    CHANGE? • YOU WOULD HAVE TO REFACTOR CLIENT’S CODE TOO • WHAT IF YOU WANT HAVE A SINGLE INSTANCE OF DEPENDENCY IN ALL CLIENTS? • YOU WOULD HAVE TO CREATE FACTORY METHODS AND CLASSES
  5. Dependency Injection ”Dependency injection means giving an object its instance

    variables. Really. That's it.” - James Shore SIMPLE DEFINITION
  6. Dependency Injection Passing the dependency to the client, rather than

    allowing a client to build or find the dependency, is the fundamental requirement of the pattern LONGER DEFINITION IN SOFTWARE ENGINEERING, DEPENDENCY INJECTION IS A SOFTWARE DESIGN PATTERN THAT IMPLEMENTS INVERSION OF CONTROL FOR RESOLVING DEPENDENCIES. DEPENDENCY : AN OBJECT THAT CAN BE USED INJECTION : AN INJECTION IS THE PASSING OF A DEPENDENCY TO A DEPENDENT OBJECT (A CLIENT) THAT WOULD USE IT.
  7. With Dependency Injection public class ClientClass {
 
 private DependencyClass

    dependency;
 
 // Injection via constructor
 public ClientClass(DependencyClass dependency) {
 this.dependency = dependency;
 }
 
 // Injection via method
 public void setDependency(DependencyClass dependency) {
 this.dependency = new DependencyClass();
 }
 …
 } public class MyInjector { public static void main(String[] args) {
 ClientClass clientClass1 = new ClientClass(new DependencyClass());
 }
 }
  8. With Dependency Injection public class ClientClass {
 
 // Field

    injection
 @Inject DependencyClass dependency;
 
 // Injection via constructor
 @Inject
 public ClientClass(DependencyClass dependency) {
 this.dependency = dependency;
 }
 
 // Injection via method
 @Inject
 public void setDependency(DependencyClass dependency) {
 this.dependency = new DependencyClass();
 }
 
 }
  9. Dependency Injection Advantages • CLIENTS NEED NOT CARE OF HOW

    DEPENDENCIES ARE CONSTRUCTED • DECOUPLED CODE • CHANGING THE IMPLEMENTATION BECOMES EASIER • CAN PROVIDE MOCK IMPLEMENTATION FOR TESTING
  10. Dependency Injection Libraries • SPRING • GOOGLE GUICE (VERY LARGE

    (REMEMBER METHOD LIMIT EXCEEDED), SLOW) • ROBOGUICE (GUICE’S IMPLEMENTATION ON ANDROID SLOW) • DAGGER 1 • DAGGER 2
  11. Dagger 1 • FAST • EASY TO USE, USES ANNOTATIONS

    TO CONFIGURE DEPENDENCIES • EASY ACCESS TO SHARED INSTANCES VIA @INJECT • REPLACEABLE MODULES WHICH HELPS IN TESTING
  12. Dagger 1 - Issues • DEPENDENCY GRAPH COMPOSITION AT RUNTIME

    • HURTS PERFORMANCE • ERRORS COULD BE KNOWN ONLY AT RUNTIME • PROGUARD CONFIGURATION ISSUES • GENERATED CODE HARD TO UNDERSTAND AND FOLLOW AS IT USED REFLECTION
  13. Dagger 2 • DEPENDENCY GRAPH COMPOSITION AT COMPILE TIME •

    CODE GENERATION AT COMPILE TIME - NO ISSUED WITH PERFORMANCE • ERRORS COULD BE KNOWN WHILE COMPILING • PROGUARD CONFIGURATION NOT REQUIRED • GENERATED CODE EASY TO UNDERSTAND
  14. Dagger 2 in Android • DO YOU USE SHARED INSTANCES?

    • APPLICATION WIDE SHARED INSTANCES • ACTIVITY WIDE SHARED INSTANCES (WHICH CAN BE SHARED BY FRAGMENTS AND PRESENTERS) • DO YOU WANT TO MOCK NETWORK ACCESS DURING TESTING? • WANT DIFFERENT IMPLEMENTATIONS FOR DIFFERENT BUILD FLAVOURS?
  15. Dagger 2 in Android • SIMPLIFIES ACCESS TO SHARED INSTANCES

    • SHARED INSTANCES CAN BE SCOPED • REPLACE MODULES FOR EASIER TESTING public class MainActivity extends AppCompatActivity {
 
 @Inject MyServerApiClient apiClient;
 @Inject FoursquareApiClient foursquareApiClient; … }
  16. @Inject FIELD INJECTION CONSTRUCTOR INJECTION METHOD INJECTION public class MainActivity

    extends AppCompatActivity {
 
 @Inject MyServerApiClient apiClient;
 @Inject FoursquareApiClient foursquareApiClient;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 DaggerDemoApplication.getAppComponent().inject(this);
 } 
 … } @Inject TELLS DAGGER TO INJECT A DEPENDENCY
  17. @Inject FIELD INJECTION CONSTRUCTOR INJECTION METHOD INJECTION @Inject TELLS DAGGER

    TO INJECT A DEPENDENCY 
 public class DataStore {
 
 private final SharedPreferences sharedPreferences;
 @Inject
 public DataStore(SharedPreferences sharedPreferences) {
 } … CANNOT BE USED IN ANDROID ACTIVITIES, FRAGMENTS AND SERVICES
  18. @Inject FIELD INJECTION CONSTRUCTOR INJECTION METHOD INJECTION @Inject TELLS DAGGER

    TO INJECT A DEPENDENCY 
 public class DataStore {
 
 private SharedPreferences sharedPreferences;
 
 public DataStore() {
 } @Inject public foo(SharedPreferences sharedPref) { this.sharedPreferences = sharedPref; } …
  19. @MODULE • CLASS ANNOTATED WITH @MODULE • CONTAINS PROVIDER METHODS

    @Module SIGNALS DAGGER TO SEARCH FOR INSTANCES IN THE METHODS @Module
 public class ApiModule {
 
 @Singleton
 @Provides
 public Converter.Factory getConvertorFactory() {
 return GsonConverterFactory.create();
 } …
 
 }
  20. @Provides @Provides ANNOTATION FOR INSTANCE PROVIDER METHOD @Module
 public class

    ApiModule {
 
 @Singleton
 @Provides
 public Converter.Factory getConvertorFactory( return GsonConverterFactory.create();
 } …
 
 } • PRESENT IN MODULES • ANNOTATES PROVIDER METHODS • PRESENT ALONG WITH SCOPE - SINGLETON OR CUSTOM SCOPE • METHOD NAME DOES NOT MATTER
  21. @Component @Component ASSIGNS REFERENCES IN OUR ACTIVITIES, SERVICES, OR FRAGMENTS

    TO HAVE ACCESS TO SINGLETONS WE DEFINED IN @MODULE. • DEFINES WHICH MODULE WILL BE USED • INDIVIDUAL ‘INJECT’ METHOD TO SHOW WHICH CLIENT CLASSES WOULD BE INJECTED @Component(modules = {
 ApiModule.class
 })
 public interface AppComponent {
 void inject(MainActivity mainActivity);
 }

  22. • Manage instances that can last • The entire application

    lifecycle OR • Activity lifecycle • Custom scope like user session @SCOPE ActivityScope Application scope
  23. @Scope @Scope @Module
 public class ActivityModule {
 
 private final

    Activity activity;
 
 public ActivityModule(Activity activity) {
 this.activity = activity;
 }
 
 @ActivityScope
 @Provides
 public Activity providesActivity() {
 return this.activity;
 }
 
 }