Fundamentals of Dependency Injection and popular libraries in Android

Ankit Sinhal
AndroidPub
Published in
4 min readAug 24, 2017

Dependency injection is quite interesting topic and to understand it perfectly it is very important to learn the basics of it and learn it in depth. So I am planning to explain it in two parts.

This post will explain what dependency injection is, its benefit and different popular DI options which we can use in our Android projects. It seems little theoretical to you to grasp the basics. So let’s gets started…

“With good basics you’ll have endless options”

What is Dependency Injection?

Any business application is made up of two or more classes and these classes collaborate with each other to perform some operation. Traditionally, we create the instance of dependent class object and do the required operations. When applying Dependency Injection, the objects are given their dependencies at creation time by some external entity that coordinates each object in the system. It means dependencies are injected into objects.

In other words, Dependency injection is a style of object creation in which an objects are created by an external entity, or technique whereby one object supplies the dependencies of another object.

It is built upon the concept of Inversion of Control which says “Rather than low level code calling up to high level code, high level code can receive lower level code that it can call down to. This inverts the typical control pattern seen in procedural programming.”

How Dependency Injection works?

Most dependency injectors rely on reflection to create and inject dependencies. Reflection is awesome but is very slow and time consuming. Also it perform dependency resolution at runtime which leads unexpected errors and crashes the application.

On the other hand some injectors uses a Pre-compiler that creates all the classes (object graph) it needs to work using Annotation Processor. An Annotation Processor is a way to read the compiled files during build time to generate source code files to be used in the project. So it perform the dependency resolution before the application runs and avoid unexpected errors.

Dependency Injection Modes

There are three common means for a client to accept a dependency injection:

  • Constructor based injection
  • Setter method
  • Interface

Benefits of DI

Dependency Injection reduces to write boiler plate code and make the development process smooth. Implementing proper dependency injection in our apps allows us to have:

  • Loose coupling
  • Easily testable code
  • Code reusability

Popular Libraries comparison

The available popular dependency injection libraries for Android are:

  • RoboGuice
  • ButterKnife
  • Dagger
  • Android Annotation

Let’s have comparison on above dependency injection libraries :

RoboGuice

Roboguice injects code at runtime using reflection. Using RoboGuice, we can inject Views, Drawable, Resources, System Service, or any other objects. Because of using reflection it is slow.

Traditional code:

TextView textView = (TextView) findViewById(R.id.textView);

Roboguice inject view code:

@InjectView(R.id.textView) TextView textView;

ButterKnife

Butterknife uses annotation processing to generate modified Java classes based on annotations. It allows to annotate the views and OnClickListeners. Butterknife also includes findById methods which simplify code that still has to find views on a View, Activity, or Dialog.

Traditional code:

TextView textView = (TextView) findViewById(R.id.textView);

Butterknife code:

@BindView(R.id. textView) TextView textView;

Traditional code:

button.setOnClickListener(new OnClickListener(){@overridepublic void onClick(View view){}})

Butterknife code:

@OnClick(R.id.button)

Dagger

Dagger is designed for low-end devices. It is based on the Java Specification Request (JSR) 330. It uses code generation and is based on annotations. The generated code is very relatively easy to read and debug.

Dagger 2 uses the following annotations:

  • @Module and @Provides: define classes and methods which provide dependencies
  • @Inject: request dependencies. Can be used on a constructor, a field, or a method
  • @Component: enable selected modules and used for performing dependency injection

Conclusion

Using dependency injection framework may be attractive because it simplify the code we write and also provide an adaptive environment that’s useful for testing and other configuration changes.

RoboGuice is a cool idea in theory and very powerful. It does a lot of the same things Butterknife can do but it does them at runtime using reflection. This causes a performance impact.

Dagger and Butterknife seems to handle both the dependency inject and view injection with less of a performance impact.

On next post we will get some practical and coding work.

Thanks for reading. To help others please click ❤ to recommend this article if you found it helpful.

Stay tuned for upcoming articles. For any quires or suggestions, feel free to hit me on Twitter Google+

Check out my blogger page for more interesting topics on Software development.

--

--

Ankit Sinhal
AndroidPub

Senior Software Engineer at Walmart. Dreamer and Achiever..