In this guide, you’ll learn what Dependency Injection (DI) is, why it’s important, and how to implement it in your .NET Core applications. We’ll keep it beginner-friendly with simple code examples and relatable real-life analogies.
What is Dependency Injection?
Imagine you own a restaurant. You (the owner) need a chef to cook the food. Instead of hiring a chef directly inside your kitchen class, what if someone provided you with a trained chef from a Chef Service? That way, if you ever want to switch chefs, you don’t have to change your kitchen.
This is the basic idea behind Dependency Injection (DI).
In programming terms:
- Your class (like Kitchen) depends on another class (Chef).
- Dependency Injection means providing that dependency (Chef) from the outside instead of creating it inside the class.
This helps with:
- Loose coupling
- Easier testing
- Better scalability
Dependency Injection Vs Without Dependency Injection
Let’s say you drive a car:
- Without DI: Your car creates its own engine. (Possible? LOL. You need the Taarzan The Wonder Car)
- With DI: The engine is provided to the car when it’s assembled. This makes it easy to replace or upgrade the engine without changing the car’s internal code. (Which is practical)
Now as we have understood what is dependency injection in .NET Core, we will proceed with
Types of Dependency Injection
1. Constructor Injection (most common)
The dependency is passed via the class constructor.
public class Car
{
private readonly IEngine _engine;
public Car(IEngine engine)
{
_engine = engine;
}
public void Drive() => _engine.Start();
}
2. Method Injection (less common)
Injected via method parameters.
3. Property Injection (rarely used)
Dependencies are set via public properties.
Dependency Injection in .NET Core
.NET Core has a built-in Dependency Injection container. This is a fancy way of saying it handles all the wiring up of your classes for you.
Main Components:
- IServiceCollection: Used to register services.
- IServiceProvider: Used to retrieve instances.
When we are registering services via dependency injection, we can specify the life time of the services.
Service Lifetimes
When registering dependencies, you need to specify their lifetime:
Lifetime | Description | Use Case |
Transient | New instance every time it’s requested | Lightweight, stateless services |
Scoped | One instance per HTTP request | Web apps, per-user logic |
Singleton | One instance for the entire application lifetime | Shared configuration, logging |
Lets jump to the code playground now, we will create a simple Console App that will greet your name and here we will use dependency injection.
Code Example – DI in a Console App
Step 1. Define the interface and class
public interface IGreetingService
{
void Greet(string name);
}
public class GreetingService : IGreetingService
{
public void Greet(string name)
{
Console.WriteLine($"Hello, {name}!");
}
}
2. Register and resolve dependencies
var services = new ServiceCollection();
services.AddTransient<IGreetingService, GreetingService>();
var provider = services.BuildServiceProvider();
var greeter = provider.GetRequiredService<IGreetingService>();
greeter.Greet("Supriyo");
That’s all! You’ve just used Dependency Injection in a .NET Core console app.
Okay you learned DI, but you are a beginner so you need to know what are the common mistakes to avoid.
Common Mistakes to Avoid
- Forgetting to register the interface
- Using Singleton for services that hold user-specific data
- Injecting services in static classes
Summary
Dependency Injection is a powerful pattern that promotes loose coupling and makes your .NET applications easier to test, maintain, and scale.
With .NET Core, using DI is not only encouraged—it’s built-in! Mastering it early will make your development journey much smoother.
This is a quick article to understand Dependency Injection in .NET Core. Let me know you want a detailed post.
Happy Coding!