.NET Core  

Dependency Injection in .NET Core Using IServiceCollection

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.