What is dependency injection, and why would you use it?
Design patternsJunior
In shortDependency injection means a class gets the objects it depends on from outside instead of creating them itself. It makes code easier to test and to change.
Model answer
A class depends on other objects to do its job: a repository, an API client, a clock. With dependency injection, it doesn’t create them; it receives them, usually through the constructor.
// Without DI: the ViewModel builds its own repository and can't be tested with a fake
class ProfileViewModel : ViewModel() {
private val repository = ProfileRepository(RetrofitClient.api)
}
// With DI: the repository is passed in
class ProfileViewModel(private val repository: ProfileRepository) : ViewModel()
Why it helps:
- Testing. In a unit test you pass a fake repository that returns fixed data, with no network.
- Flexibility. You can switch from Retrofit to Ktor, or from a real clock to a fixed one, without touching the class.
- Clear dependencies. The constructor shows exactly what the class needs.
Frameworks like Hilt, Koin or Spring create and wire the objects for you, which helps in big apps. But passing a parameter to a constructor is already dependency injection.
What they're looking for
A plain definition, a concrete example with constructor injection, and the testing benefit. Bonus points for knowing DI doesn't require a framework.
Common mistakes
- Defining it only as "using Hilt" or "using Spring".
- Not giving an example.
- Confusing it with the Service Locator pattern.
More design patterns questions
- When would you use the Builder pattern, and do you need it in Kotlin or Swift?Mid-level
- When would you use the Decorator pattern instead of inheritance?Mid-level
- What are the SOLID principles? Give an example of one you've applied.Junior
- What's the difference between the State and Strategy patterns?Mid-level