DAGGER - Hilt - Dependency Injection
Dependency injection is a design pattern and not a library
Is a compile time android dependency injection framework
Dependency injection makes it easy to create loosely coupled components, which means that components consume functionality defined by interfaces without having any knowledge of which implementation classes are being used.
Reduces the boilerplate codes
Enhances code reusability and decouples dependencies
Refactoring becomes easy
Testing becomes easy
It allows our code to be more loosely coupled because classes do not have hard-coded dependencies
Dagger :
- Is a fully static compile time dependency framework for Java, Kotlin and android
- Works at compile time i.e it automatically generates the codes for DI that we need to write manually
- It generates the AppContainer automatically during compile time
- It creates factory for classes available in the application graph to satisfy dependencies
- Decides whether to reuse the dependency or create a new instance with the help of scopes
There are 2 types of Manual Dependency Injection
- Constructor Injection
- Field Injection
- Reflection Based Solution which generated dependency at runtime
- Static Solution that generates the code to provide dependency at compile time
- Dagger
- Hilt
Create a BaseApplication class and extend it with Application class
@HiltAndroidAppNow add the BaseApplication in the Manifest file
class BaseApplication : Application()
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.keshav.test">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".BaseApplication"
android:theme="@style/Theme.Test">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
class Car {
@Inject
constructor()
fun getCar() {
Log.d("Main", "Car is Running")
}
}
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var car : Car
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
car.getCar()
}
}
Now lets create Wheels and Engine class and inject them like we did with the Car class.
class Wheels {
@Inject
constructor()
fun getWheels() {
Log.d("Wheels", "Wheels are Rotating")
}
}
class Engine {
@Inject
constructor()
fun getEngine() {
Log.d("Engine", "Engine Started")
}
}
class Car @Inject constructor(private val engine : Engine, private val wheels :Wheels) {
fun getCar() {
engine.getEngine()
wheels.getWheels()
Log.d("Main", "Car is Running")
}
}
----------------------------------------------------------------------------------------------------------------------------
Eg : Car -> engine and wheels
Engine -> Sparkplug, blocks, cylinders, petrol, diesel
Wheels -> tyres, rims
Need to instantiate all the above classes and any changes made in any of the classes may need changes in every place where its been used.
DAGger - (Directed Acyclic Graph)ger
Component creates and stores our object and provides them to us. Can also called as the injector
2 ways the injector can provide us dependencies.
Either they can inject them into member variable of our activity directly or by provision method which is basically a simple getter method
Compile time verification of dependency to avoid app crash during runtime
Comments
Post a Comment