Dependency Injection in Android
=============================
What is Dependency Injection (DI)?
---------------------------------
Dependency Injection is a design pattern used to implement IoC (Inversion of Control), which allows
the creation of dependent objects outside of a class and provides those objects to a class through
different ways.
Benefits of DI:
- Promotes loose coupling between classes.
- Increases testability and maintainability.
- Improves code reusability.
Key Concepts:
-------------
1. Dependency: An object that another object relies on.
2. Injection: The process of passing a dependency to a dependent object.
Example:
--------
Without DI:
class Engine {
fun start() = "Engine started"
}
class Car {
private val engine = Engine()
fun start() = engine.start()
}
Here, Car creates its own Engine, making it tightly coupled.
With DI:
class Engine {
fun start() = "Engine started"
}
class Car(private val engine: Engine) {
fun start() = engine.start()
}
Now, Engine is injected into Car, making Car more flexible and testable.
Types of Dependency Injection:
------------------------------
1. Constructor Injection:
Dependencies are provided through the class constructor.
2. Field Injection:
Dependencies are injected directly into fields using annotations.
3. Method Injection:
Dependencies are provided through a method call.
Popular DI Libraries in Android:
--------------------------------
1. Dagger 2:
A fully static, compile-time framework for dependency injection.
2. Hilt (built on top of Dagger):
Provides a standard way to incorporate DI into Android applications.
3. Koin:
A lightweight DI framework written in Kotlin.
Hilt Example:
--------------
1. Add dependencies in build.gradle:
dependencies {
implementation "com.google.dagger:hilt-android:2.x"
kapt "com.google.dagger:hilt-compiler:2.x"
}
2. Annotate the Application class:
@HiltAndroidApp
class MyApp : Application()
3. Provide dependencies using @Module and @Provides:
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideEngine(): Engine = Engine()
}
4. Inject into Activity:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var engine: Engine
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
println(engine.start())
}
}
Conclusion:
-----------
Dependency Injection is an essential tool for building scalable and maintainable Android
applications. By decoupling dependencies, it improves code readability, testability, and flexibility.