Slide 1

Slide 1 text

DAGGER 2 IN ANDROID GAURAV VASHISTH

Slide 2

Slide 2 text

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();
 …
 }
 }

Slide 3

Slide 3 text

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?

Slide 4

Slide 4 text

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();
 …
 }
 }

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Dependency Injection ”Dependency injection means giving an object its instance variables. Really. That's it.” - James Shore SIMPLE DEFINITION

Slide 7

Slide 7 text

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.

Slide 8

Slide 8 text

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());
 }
 }

Slide 9

Slide 9 text

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();
 }
 
 }

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Dependency Injection How? • WRITE IT ALL YOURSELF OR • USE DEPENDENCY INJECTION LIBRARIES

Slide 12

Slide 12 text

Dependency Injection Libraries • SPRING • GOOGLE GUICE (VERY LARGE (REMEMBER METHOD LIMIT EXCEEDED), SLOW) • ROBOGUICE (GUICE’S IMPLEMENTATION ON ANDROID SLOW) • DAGGER 1 • DAGGER 2

Slide 13

Slide 13 text

Dagger 1 • FAST • EASY TO USE, USES ANNOTATIONS TO CONFIGURE DEPENDENCIES • EASY ACCESS TO SHARED INSTANCES VIA @INJECT • REPLACEABLE MODULES WHICH HELPS IN TESTING

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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?

Slide 17

Slide 17 text

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; … }

Slide 18

Slide 18 text

DAGGER 2 INGREDIENTS

Slide 19

Slide 19 text

@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

Slide 20

Slide 20 text

@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

Slide 21

Slide 21 text

@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; } …

Slide 22

Slide 22 text

@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();
 } …
 
 }

Slide 23

Slide 23 text

@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

Slide 24

Slide 24 text

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


Slide 25

Slide 25 text

• Manage instances that can last • The entire application lifecycle OR • Activity lifecycle • Custom scope like user session @SCOPE ActivityScope Application scope

Slide 26

Slide 26 text

@Scope @Scope @Scope
 @Retention(value = RetentionPolicy.RUNTIME)
 public @interface ActivityScope {
 }

Slide 27

Slide 27 text

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


Slide 28

Slide 28 text

EXAMPLE CODE

Slide 29

Slide 29 text

Look out for • http://google.github.io/dagger/. • https://medium.com/@patrykpoborca/making-a-best-practice-app-4-dagger-2-267ec5f6c89a • https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2 • http://fernandocejas.com/2015/04/11/tasting-dagger-2-on-android/ • http://www.vogella.com/tutorials/Dagger/article.html