Developer’s Commute
La
Dependency
Injection
UNDERSTANDING DEPENDENCY INJECTION
La Dependency Injection Developers Commute
Table of Contents
Part 0 Prerequisites to
Dependency Injcetion
What is Dependency Injection
Benefits and need of Dependency Injection
What is Manual Injection
Implementation of Manual Injection
Why do we need Dependency
Injection Frameworks
Why is Dagger Hilt better than Dagger 2
Dagger Hilt Basics
Annotations of Dagger Hilt Part 1
Annotations of Dagger Hilt Part 2
Annotations of Dagger Hilt Part 3
Annotations of Dagger Hilt Part 4
Annotations of Dagger Hilt Part 5
Annotations of Dagger Hilt Part 6
La Dependency Injection Developers Commute
Table of Contents
---------Coming Soon---------
Dagger Hilt CheatSheet
Implementation of Dagger Hilt
Implementing Dagger Hilt Inside a project
Testing Dagger Hilt in Android
Project
Debugging Android Project
Solid Principle and Dependency Injection
How to design Classes Effectively in
Dependency Injeciton
Interview Questions for DI Part 1
Interview Questions for DI Part 2
Interview Questions for DI Part 3
Interview Questions for DI Part 4
Learning from Documentation Part 1
Learning from Documentation Part2
Learning from Documentation Part 3
Learning from Documentation Part 4
Learning from Documentation Part 5
La Depedency Injection Developer’s Commute
Chapter 1
Part 0 Prerequisites to
Dependency Injcetion
La Dependency Injection Developer’s Commute
Chapter 1
Prerequisites to
Dependency
Injcetion
Before we start exploring Dependency Injection, there are
some prerequisites that you need to understand.
→ Kotlin Basics
→ Have Created some small Apps before
→ Understanding of Retrofit and APIs
→ Understanding of Objects and Classes in Kotlin
→ Understanding the Basics of Android Development
Kotlin Basics:
If you have learned Kotlin and have done some
programming in Kotlin, then you are good to go. If not try
understanding the basics of Kotlin first.
Have Created Some Small Apps Before:
If you haven’t created any Android apps before then you
might not be able to understand Dependency Injection.
Therefore I suggest creating some basic apps with API
calls.
La Dependency Injection Developer’s Commute
Chapter 1
Understanding of Objects and Classes in Kotlin:
if you do not understand Oops concepts and the
difference between objects and classes then you might
not be able to understand Dependency Injection,
Here is the basic difference between Objects and Classes:
→ What are Objects and Classes in Kotlin?
Classes are the Blueprint of the objects.
Objects are the instances of the classes.
It can be easily understood as:
Class→ Car
Object → Ferrari
Car is the Blueprint of Ferrari → Class
Ferrari is the type of car → Object
Understanding the Basics of Android Development:
If you do understand the basics of Android Development
then I would suggest reading Android Documentation
first.
La Depedency Injection Developer’s Commute
Chapter 2
What is Dependency
Injection
La Dependency Injection Developer’s Commute
Chapter 2
What is
Dependency
Injection
It is needed when a class may require another object to
function properly
So when we inject an object into the class which is
dependent on it for its functionality it is called a
dependency Injection
It can be done manually but a framework is always
preferred
Because it reduces a lot of code and keeps everything
consistent
Framework makes it easier for new programmers to
understand the code.
Let me explain :
Suppose there is a Car
A car is dependent on its Engine system to work
properly
La Dependency Injection Developer’s Commute
Chapter 2
A car is dependent on its Break system to work
properly
A car is dependent on its Gear system to work properly
This is called Dependency
When we put or Inject these systems inside our cars.
So that it may serve its purpose.
This is called an Injection
Injection
Dependency Engine
Car
Dependency
Injection
Wheel
La Dependency Injection Developer’s Commute
Chapter 2
When a car class is dependent on an Engine class to work
properly.
When we inject our Engine class into our Car class it is
called Dependency Injection
So when we inject a class into a class that is
dependent on it for its functionality
It is called a dependency Injection
Injection
Dependency Engine
Car
Dependency
Injection
Wheel
La Depedency Injection Developer’s Commute
Chapter 3
What are Benefits and
need of Dependency
Injection
La Dependency Injection Developer’s Commute
Chapter 3
What are the benefits and
need of Dependency
Injection
Dependency Injection is beneficial for app developers:
Introduces Code Reusability
Improves Single Responsibility
Makes class more Testable
Makes Code more extensible
You might not understand this part fully because we
haven’t talked about Dagger Hilt and Manual Injection
yet. It will become clear over time.
How does it increase code Reusability?
Dependency Injection allows us to reuse code again
and again
Without creating a lot of messy boilerplate code
For example - The module allows us to inject a lot of
code easily
La Dependency Injection Developer’s Commute
Chapter 3
How does it Improve Single Responsibility?
Single Responsibility means that the class has the
responsibility of carrying out a particular function
When we inject Dependencies, the class does not
need to create objects of those injections.
Therefore it focuses on its single-function
How does it make the Classes More Testable?
Dependency Injection reduces a lot of boilerplate
code thus making testing efficient in nature
We can easily track dependencies and find the code
that is not working properly
How does it make code more Extensible?
More parts of code can be added easily
Parts of the code can be easily implemented and
injected where we want.
Why is it Needed?
It is needed when a class may require another class to
function properly. If we do not provide the object of
another class then we will not be able to call all the
functions inside of our class.
La Dependency Injection Developer’s Commute
Chapter 3
Let me give you an example of a class that requires
another class to function properly.
Car -> Class needs Engine and Wheel Class to function
properly.
If I do not provide a wheel or Engine to the car then it
will not be able to run.
Therefore it is essential that we provide objects of
Engine and Wheel classes to the car class.
As we can see that the car Class needs Engine and Wheel to run
the getEngine and getWheel functions therfore we need to provide
these two classes as injection to the car class
La Depedency Injection Developer’s Commute
Chapter 4
What is Manual Injection
La Dependency Injection Developer’s Commute
Chapter 4
What is Manual
Injection
When we try to inject the classes manually instead of
using any frameworks then it is called Manual Injection.
Manual Injection is not preferred over frameworks
because of a lot of boilerplate code. It also makes the
code hard to understand as dependency injection might
be implemented in different ways by different developers.
In the case of the Dependency framework, the boiler
code is eliminated and it introduces a pattern of
implementing injections.
Therefore, it becomes easier to understand for new
developers as well as easy to debug and test.
However manual injection plays an important role in
Android development. In order to understand any DI
effectively, you must understand how to implement
manual injection as the frameworks are the abstraction of
over manual injection code.
La Depedency Injection Developer’s Commute
Chapter 5
Implementation of
Manual Injection
La Dependency Injection Developer’s Commute
Chapter 5
How can it be done manually?
We can simply Inject the Engine class through a
constructor of the car class
But complexity arises when multiple classes need the
same class.
What if there are bike, truck etc classes that are also
dependent on the Engine class?
Injecting Engine class, again and again, becomes
complex in nature
That is when Frameworks become necessary
La Dependency Injection Developer’s Commute
Chapter 5
→ Here we can see that the car class requires the
engine and Wheel class to function properly.
→ Car class will not be able to call the getEngine and
getwheel functions without injection of these two
classes
→ This simply means that car class is dependent on
these two classes
→ The flow of the program: →
→ When the car class is called it is constructed by
calling the Engine and Wheel classes.
→ Then the function of get car is called, where first
getEngine function is executed and it Logs “Engine
Started” and then getWheel is called and it Logs
“wheel started”. Then getCar logs “Car is Running”
La Dependency Injection Developer’s Commute
Chapter 5
→ We can see in the Car class that we are simply
declaring the Engine and Wheel classes. But we are
not making an object of these classes.
→ In order to call the functions inside the Engine and
Wheel class we must create an object first.
→ How can we do it in the most efficient way
possible?
→ If we call all the injection objects in a single place
then it is easier the access them. Therefore we make a
car object in the BaseApp class which takes the
Application context and declares objects of the
Engine and Wheel classes.
→ var car = Car(Engine(), Wheel()) → Car object is
declared and it is injected with Engine and Wheel
objects.
Wheel Object
Engine Object
Car Object
La Dependency Injection Developer’s Commute
Chapter 5
→ Baseapp itself is a class and if we need to call its
internals then we must create an object of this class.
→ We create an object of the Baseapp class in
MainActivity and simply call the car object.
→ Car class has already been injected with the Engine
and Wheel objects so it will execute all the functions
smoothly.
Base Class variable is declared in the main activity and its object is
created. We do not need to create multiple objects of car, Engine or
Wheel as we have already called them in the base class. Then get car
function is called.
La Depedency Injection Developer’s Commute
Chapter 6
Why do we need
Dependency Injection
Frameworks
La Dependency Injection Developer’s Commute
Chapter 6
Why do we need
Dependency Injection
Frameworks
Dependency Injection can be done manually but a
framework is always preferred
Because it reduces a lot of code and keeps everything
consistent
Framework makes it easier for new programmers to
understand the code.
Let's consider that there are multiple vehicle classes like a
car class, truck class and bike class
→ Car Class
→ Bike Class
→ Truck Class
All of these classes require Engine and Wheel classes to
function properly.
La Dependency Injection Developer’s Commute
Chapter 6
If we want to do manual injection of these classes then
we need to declare them in a single Baseclass.
→ var car = Car(Engine(), Wheel())
→var Bike = Bike(Engine(), Wheel())
→var Truck= Truck(Engine(), Wheel())
Declaring all these classes and then injecting all the
objects inside of them becomes a complex process
Therefore we need a framework that makes objects of
these classes automatically and injects them wherever we
want.
Here comes the need for dependency Injection
frameworks like:
Dagger Hilt
Dagger 2
Koin
Dependency Injection Framework uses annotations for
the process of creating objects and injecting them.
La Depedency Injection Developer’s Commute
Chapter 8
Why is Dagger Hilt
Prefered over Dagger 2
La Dependency Injection
Chapter 7
Why is Dagger Hilt Developer’s Commute
Prefered over Dagger
2
Annotations provided by Hilt are standardized.
You don't need to implement your own annotations
like in the case of Dagger 2
These standard annotations form a layer on top of
other annotations
Therefore one annotation acts as the parent other
becomes its sub-annotations that inherit from the
parent
To understand more pls refer to the documentation
I am not explaining this part because we are not
exploring Dagger 2 in this ebook. Instead, our focus is to
understand the Dagger Hilt and its usage.
Overtime I will also produce an ebook related to Dagger 2
La Depedency Injection Developer’s Commute
Chapter 9
Dagger hilt Basics
La Dependency Injection
Chapter 9
Dagger Hilt
Basics
Developer’s Commute
As of now, we know that Dependency Injection can be
implemented in many ways.
Koin
Dagger Hilt
Dagger 2
However, the Dagger hilt is the most used way to
implement dependency injection nowadays.
Why is it preferred over other methods?
Dagger Hilt is easier than Dagger 2
Hilt is just a wrapper around Dagger 2
For now, it has become a standard way to implement
DI
Behind the scenes, it generates Dagger code
Knowing about Dagger 2 will make it easier to
understand, But you don't necessarily need it
La Dependency Injection Developer’s Commute
Chapter 9
Dagger 2 has a lot of customization options with
annotations, hilt just streamlines it by introducing
patterns.
For example - Dagger 2 code targets different
components and we can declare these components on
top of our activities.
Like Singelton Compoenent
However, with Dagger Hilt, a tree of components is used
in case of annotations.
La Dependency Injection Developer’s Commute
Chapter 9
Overall Dagger Hilt just streamlines our code and gives us
fewer annotations to worry about.
Dagger 2 has a lot of methods and implementations
Hilt just streamlines it
To implement Hilt inside your app
You need to add dependencies and some plugins like
Kotlin-Kapt
Kapt -> Kotlin Annotation Processing Tool (Refer to the
documentation part)
Dagger works similarly to Dagger 2 with Annotations
Plugins -> Implemented in Root Build gradle file
plugins {
...
id("com.google.dagger.hilt.android") version "2.44" apply
false
}
Dependencies -> Implemented in App Gradle File
plugins {
kotlin("kapt")
id("com.google.dagger.hilt.android")
}
dependencies {
implementation("com.google.dagger:hilt-android:2.44")
kapt("com.google.dagger:hilt-android-compiler:2.44")
}
kapt {
correctErrorTypes = true
}
La Depedency Injection Developer’s Commute
Chapter 10
Annotations of Dagger Hilt
Part 1
La Dependency Injection
Chapter 10
Annotations of Developer’s Commute
Dagger Hilt Part 1
What is the @ HiltAndroidApp?
In order to start working with Dagger Hilt we use the
Hilt Android App annotation
It is used above Application class
It means that Hilt code generation is started in the
backend and all the boilerplate code gets written.
La Dependency Injection Developer’s Commute
Chapter 10
Previously in Manual Injection, we have seen that the
application class acted as a container for all the objects
that needed to be injected.
HiltAndroidApp annotation does exactly the same thing.
It generates a container for all the dependencies that
need to be injected.
Also with Application context, this class is available
throughout the app. Therefore dependencies can be
injected wherever we want.
La Depedency Injection Developer’s Commute
Chapter 11
Annotations of Dagger Hilt
Part 2
La Dependency Injection
Chapter 11
Annotations of
Dagger Hilt Part 2
Developer’s Commute
What is @ AndroidEntryPoint?
This annotation will be on top of your main activity
It tells Dagger about the Entry point of the injections
It simply tells us where the dependency needs to be
injected
An important thing to remember is if you use @
AndroidEntryPoint on an activity
And other activities depend on that activity
That activity also need to have @ AndroidEntryPoint
La Dependency Injection Developer’s Commute
Chapter 11
Hilt currently supports the following Android classes:
Application (by using @HiltAndroidApp)
ViewModel (by using @HiltViewModel)
Activity
Fragment
View
Service
BroadcastReceiver
La Depedency Injection Developer’s Commute
Chapter 12
Annotations of Dagger Hilt
Part 3
La Dependency Injection
Chapter 12
Annotations of
Dagger Hilt Part 3
What is @ Inject?
This annotation will be on top of every class that needs
to be injected or requires some other class injections.
@Inject annotation tells the Dagger Hilt that in order
to make an object of this class we need to first make
its constructor.
Its constructor might or might not have other classes.
If other classes are required then first their objects are
created and then injected.
La Dependency Injection Developer’s Commute
Chapter 12
If not, then simply the object of the class is created.
If we look at the FeedScreenViewModel class, it needs the
IgetFeedDetailsUsecase class in order to function properly
@Inject suggests that:
Therefore if we want to construct the
FeedScreenViewmodel class we need to first create the
IGetFeedDetailsUsecase class.
La Depedency Injection Developer’s Commute
Chapter 13
Annotations of Dagger Hilt
Part 4
La Dependency Injection
Chapter 13
Annotations of
Dagger Hilt Part 4
What is @ Module?
Suppose you want to access an object that is using a
third-party service (Like calling API from Retrofit)
Hilt does not know how to create that object because
it does not have any @ Inject constructor
Here comes the usage of @ Module
It tells us how to create that third-party object
We use @ Provides to create a third-party object (Like
this retrofit call)
The module can be better understood as a collection
of third-party objects that are required by the classes.
Like a retrofit call or Room is built inside the Module
class
The module includes many annotations:
La Dependency Injection Developer’s Commute
Chapter 13
Like a retrofit call or Room is built inside the Module
class
The module includes many annotations:
-> InstallIn(SingletonComponent::Class)
-> Provides
-> Singelton
-> Binds
-> Named Qualifiers
La Depedency Injection Developer’s Commute
Chapter 14
Annotations of Dagger Hilt
Part 5
La Dependency Injection
Chapter 14
Annotations of
Dagger Hilt Part 5
What is InstallIn(SingletonCompoenent::Class)?
Here is where Hilt shines over Dagger 2
Remember there were many components in Dagger 2
(If you don’t understand Dagger 2 no need to focus on
it)
Now these components are layered on top of each
other making it easier to access
The speciality of singleton Components is applicable
in the Application Context
We can also create an Activitycompoenent or
fragment Component if we need to
La Dependency Injection Developer’s Commute
Chapter 14
Here we can see the flow of dependency. Let me
explain:
First, Dagger hilt checks if is there any @ Inject
constructor to build the object - NO
-> We are inside the module which consists of third-party
libraries we can not add @Inject to them. That is why we
use @Provides.
Secondly goes to the activity component is there any
@ provides here - NO
Thirdly goes to the activity retained component are
there any @ provides - No
Fourthly goes to the Singelton component - Here he
finds the @ provides
Constructs the object and injects it where it is needed
La Depedency Injection Developer’s Commute
Chapter 15
Annotations of Dagger Hilt
Part 6
La Dependency Injection
Chapter 15
Annotations of Dagger
Hilt Part 6
What is @ Binds?
Now suppose Hilt already knows how to create an
object (We have implemented @ Inject constructor on
it)
We want to give the interface as an injection instead
of a class
We can not give interface @Inject. Therefore we bind
Interface with Class.
We want to give the interface as injection because it
makes testing easier.
Here in this example, we are binding a class called
MyDependencyImpl to an interface My dependency
La Dependency Injection
Resources :
Dependency Injection Thread 1
Dependency Injection Thread 2
Dependency Injection Thread 3
Dependency Injection Thread 4
Dependency Injection Thread 5
Dependency Injection Blog