Dependency Injection (DI) is a design pattern that enables the development of loosely coupled code. .NET Core has built-in support for DI, making it easy to manage dependencies in modern applications.
In this article, we’ll explore how DI works in .NET Core using the IServiceCollection
interface and walk through a simple example.
🔧 What Is Dependency Injection?
Dependency Injection is a technique where an object receives its dependencies from an external source rather than creating them itself. This makes the application easier to maintain, test, and scale.
🧱 Key Components in .NET Core DI
IServiceCollection
– Used to register dependencies (services).
ServiceProvider
– Used to resolve dependencies.
- Service Lifetimes
Singleton
: One instance for the application lifetime.
Scoped
: One instance per request.
Transient
: A new instance every time.
✅ Example. Setting Up DI in a .NET Core Console Application
Let’s create a simple console app that demonstrates DI.
Step 1. Define Interfaces and Implementations
// IGreeter.cs
public interface IGreeter
{
void Greet(string name);
}
// ConsoleGreeter.cs
public class ConsoleGreeter : IGreeter
{
public void Greet(string name)
{
Console.WriteLine($"Hello, {name}!");
}
}
Step 2. Set Up DI with IServiceCollection
// Program.cs
using Microsoft.Extensions.DependencyInjection;
using System;
class Program
{
static void Main(string[] args)
{
// Step 1: Create a new service collection
var serviceCollection = new ServiceCollection();
// Step 2: Register services
serviceCollection.AddTransient<IGreeter, ConsoleGreeter>();
// Step 3: Build the service provider
var serviceProvider = serviceCollection.BuildServiceProvider();
// Step 4: Resolve and use the service
var greeter = serviceProvider.GetRequiredService<IGreeter>();
greeter.Greet("Alice");
}
}
📌 Explanation
AddTransient<IGreeter, ConsoleGreeter>()
: Registers ConsoleGreeter
as the implementation for IGreeter
. A new instance is created every time it’s requested.
BuildServiceProvider()
: Compiles the service registrations into a container that can resolve services.
GetRequiredService<IGreeter>()
: Requests an instance of IGreeter
. The DI container automatically injects the correct implementation.
💡 When to Use Which Lifetime?
Lifetime |
Use When... |
Singleton |
Service should be shared for the app lifetime |
Scoped |
Per web request (mostly in ASP.NET Core apps) |
Transient |
Lightweight, stateless services |
✅ Bonus: Use DI in ASP.NET Core
In ASP.NET Core, you don’t need to manually build the ServiceProvider
. Just use ConfigureServices
in Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IGreeter, ConsoleGreeter>();
}
Then, inject via the constructor:
public class HomeController : Controller
{
private readonly IGreeter _greeter;
public HomeController(IGreeter greeter)
{
_greeter = greeter;
}
public IActionResult Index()
{
_greeter.Greet("User");
return View();
}
}
🔚 Conclusion
Dependency Injection in .NET Core is simple and powerful. Using IServiceCollection
, you can register and manage dependencies with different lifetimes to keep your code clean and maintainable.
Whether you're building a console app or a large web application, understanding and applying DI is a must-have skill in .NET Core development.