What is dependency injection?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Dependency injection is a way of giving an object the collaborators it needs instead of letting it construct those collaborators itself. The pattern matters because it reduces coupling, makes code easier to test, and separates application wiring from application behavior.
The Problem Dependency Injection Solves
Imagine a class that creates its own database client, logger, and email sender internally. That class now knows too much about construction details.
This works, but it creates tight coupling. OrderService is now hard-wired to one concrete implementation. Replacing the email sender for testing or for a different environment means editing the class itself.
Dependency injection changes that relationship.
Constructor Injection Is the Most Common Form
With constructor injection, the dependency is provided from the outside.
Now OrderService depends on the abstraction EmailSender, not on one hard-coded class. Something else creates the concrete object and passes it in.
This is the core idea of dependency injection.
Why This Improves Testability
The most immediate benefit shows up in tests. You can pass a fake or mock implementation instead of the real dependency.
That means you can test OrderService without a real SMTP server, network connection, or environment configuration.
Dependency Injection Is Not the Same as a Framework
Frameworks such as Spring, ASP.NET Core, and Angular use dependency injection heavily, but the pattern itself is not tied to any framework. You can do dependency injection manually by constructing objects in one place and passing them into other objects.
A simple manual composition root looks like this:
The framework version automates this wiring, but the design principle is the same.
Common Forms of Injection
The most common styles are:
- constructor injection
- setter injection
- method parameter injection
Constructor injection is usually preferred because it makes required dependencies obvious and ensures the object is valid from the moment it is created.
Setter injection is more appropriate for optional configuration, not for essential collaborators.
Common Pitfalls
A common mistake is thinking dependency injection means “use a container.” The container is optional. The design pattern comes first.
Another issue is injecting too many dependencies into one class. That often signals that the class has too many responsibilities.
A third problem is depending on concrete implementations everywhere. Injection is most useful when classes depend on abstractions or clearly replaceable collaborators.
Summary
- Dependency injection means supplying dependencies from outside the class.
- It reduces coupling between code that does work and code that creates objects.
- Constructor injection is the clearest and most common form.
- The pattern improves testability because fake implementations are easy to provide.
- Frameworks automate dependency injection, but the idea works without any framework at all.
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.