How to Use Dependency Injection in C#

How to Use Dependency Injection in C#

How to Use Dependency Injection in C#

.NET has a built-in dependency injection container available in all project types including ASP.NET Core, console apps, and workers.

Step 1 — Define an Interface and Implementation

// IEmailService.cs
public interface IEmailService
{
    Task SendAsync(string to, string subject, string body);
}

// SmtpEmailService.cs
public class SmtpEmailService(IConfiguration config) : IEmailService
{
    public async Task SendAsync(string to, string subject, string body)
    {
        // use config["Mail:Host"] etc.
        await Task.CompletedTask; // placeholder
    }
}

Step 2 — Register with the DI Container

// Program.cs
builder.Services.AddScoped<IEmailService, SmtpEmailService>();
// Scoped  — new instance per HTTP request
// Transient — new instance every time
// Singleton — one instance for app lifetime

Step 3 — Inject into a Controller

// Controllers/OrdersController.cs
[ApiController]
[Route("api/orders")]
public class OrdersController(IEmailService emailService) : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Create(CreateOrderDto dto)
    {
        // ... create order logic
        await emailService.SendAsync(dto.Email, "Order Confirmed", "Thank you!");
        return Ok();
    }
}

Step 4 — Inject into a Background Worker

public class ReportWorker(IServiceScopeFactory scopeFactory) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            using var scope   = scopeFactory.CreateScope();
            var emailService  = scope.ServiceProvider.GetRequiredService<IEmailService>();
            await emailService.SendAsync("[email protected]", "Daily Report", "...");
            await Task.Delay(TimeSpan.FromHours(24), ct);
        }
    }
}
All Comments