Tool for HR, Hiring Managers, and the Leadership Team

Dependency Injection in .NET Core

Dependency Injection (DI) is one of the most commonly asked .NET Core interview questions.

What is Dependency Injection in .NET Core?

Dependency Injection (DI) is a design pattern where an object receives its dependencies from outside instead of creating them itself.

Without Dependency Injection (Bad Practice)
public class OrderService
{
    private EmailService _emailService;

    public OrderService()
    {
        _emailService = new EmailService(); // tightly coupled
    }

    public void PlaceOrder()
    {
        _emailService.SendEmail();
    }
}
Problems here
  • Tight coupling

  • Hard to test

  • Hard to change implementation

  • Violates SOLID principles

With Dependency Injection (Good Practice)

public class OrderService
{
    private readonly IEmailService _emailService;

    public OrderService(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public void PlaceOrder()
    {
        _emailService.SendEmail();
    }
}

Now dependency is injected from outside.

Step-by-Step Simplest Example

Step 1: Create Interface

public interface IMessageService
{
    void SendMessage();
}

Step 2: Create Implementation

public class EmailService : IMessageService
{
    public void SendMessage()
    {
        Console.WriteLine("Email Sent");
    }
}

Step 3: Register in Program.cs

(.NET 6 / .NET 7 / .NET 8)

builder.Services.AddScoped<IMessageService, EmailService>();

Step 4: Inject in Controller

public class HomeController : Controller
{
    private readonly IMessageService _messageService;

    public HomeController(IMessageService messageService)
    {
        _messageService = messageService;
    }

    public IActionResult Index()
    {
        _messageService.SendMessage();
        return View();
    }
}

That's it.
.NET Core automatically injects the dependency.

Types of Dependency Injection Lifetimes

This is very important for interviews 👇

1. Transient

New instance every time

builder.Services.AddTransient<IMessageService, EmailService>();

Use when:

  • Lightweight services

  • No shared state

2. Scoped

One instance per request (Most commonly used)

builder.Services.AddScoped<IMessageService, EmailService>();

Use when:

  • Database services

  • Business logic services

Example:

  • DbContext (Scoped)

3. Singleton

Single instance for entire application

builder.Services.AddSingleton<IMessageService, EmailService>();

Use when:

  • Caching

  • Configuration

  • Logging

Real World Example

public interface IUserRepository
{
    List<string> GetUsers();
}

public class UserRepository : IUserRepository
{
    public List<string> GetUsers()
    {
        return new List<string> { "John", "David" };
    }
}

Register:

builder.Services.AddScoped<IUserRepository, UserRepository>();

Inject:

public class UserService
{
    private readonly IUserRepository _repository;

    public UserService(IUserRepository repository)
    {
        _repository = repository;
    }

    public void GetUsers()
    {
        var users = _repository.GetUsers();
    }
}

Why Dependency Injection is Important

Interview-friendly points:

  • Loose coupling

  • Easy unit testing

  • Maintainable code

  • Better scalability

  • Follow SOLID principles

  • Easy to replace implementations

One Line Interview Answer

Dependency Injection is a design pattern where dependencies are provided to a class from outside instead of creating them inside the class, helping achieve loose coupling and better maintainability.

Constructor Injection vs Method Injection vs Property Injection

Most commonly used: Constructor Injection

Constructor Injection (Recommended)
public HomeController(IMessageService messageService)
Property Injection
public IMessageService MessageService { get; set; }
Method Injection
public void Send(IMessageService messageService)

Most Asked Interview Question

Q: Does .NET Core support DI by default?

Yes. .NET Core has built-in Dependency Injection container.

Short Real-Life Example

Think of Dependency Injection like:

You don't cook food yourself.
You order from restaurant.
Restaurant = Dependency

Your class doesn't create dependencies — they are injected.