# Dependency Injection Demystified in ASP.NET Core

Dependency Injection (DI) isn’t just a buzzword. It’s one of the reasons ASP.NET Core apps are clean, testable, and maintainable.

In this article, we’ll break down DI in the most practical way possible with code, real-world usage, and clarity.

---

## 🧠 What is Dependency Injection?

Dependency Injection is a design pattern where *dependencies (services)* are passed into a class rather than the class creating them itself.

Why?  
Because it:
- ✅ Reduces coupling
- ✅ Increases testability
- ✅ Improves code flexibility and reuse

---

## 🧰 DI in ASP.NET Core: Built-in by Default

ASP.NET Core comes with a built-in IoC (Inversion of Control) container. You register services in `Program.cs`:

```csharp
builder.Services.AddScoped<IEmailSender, SmtpEmailSender>();
```

Then inject them into your classes:

```csharp
public class AccountController : Controller
{
    private readonly IEmailSender _emailSender;

    public AccountController(IEmailSender emailSender)
    {
        _emailSender = emailSender;
    }
}
```

ASP.NET Core takes care of creating `SmtpEmailSender` and passing it in when needed.

---

## 🧩 Service Lifetimes

When registering services, choose a **lifetime**:

```csharp
// A new instance every time
services.AddTransient<IMyService, MyService>();

// One instance per request
services.AddScoped<IMyService, MyService>();

// One instance for the entire app
services.AddSingleton<IMyService, MyService>();
```

Choose wisely — especially when dealing with databases or shared state.

---

## 💡 Real-world Use Case

Let’s say you want to send SMS via multiple providers (Twilio, Vonage, etc.). You can inject a strategy pattern like this:

```csharp
public interface ISmsSender { void Send(string to, string message); }
public class TwilioSender : ISmsSender { ... }
public class TermiiSender : ISmsSender { ... }
```

Register based on config:

```csharp
if (useTwilio)
    services.AddScoped<ISmsSender, TwilioSender>();
else
    services.AddScoped<ISmsSender, TermiiSender>();
```

Then inject and call it without knowing which one you got!

---

## 🔄 Injecting Configuration

Need to inject app settings?

```csharp
builder.Services.Configure<MyAppSettings>(
    builder.Configuration.GetSection("MyAppSettings"));
```

And in your service:

```csharp
public MyService(IOptions<MyAppSettings> options)
{
    var config = options.Value;
}
```

---

## 🧪 Testability Bonus

DI makes unit testing easy. Just pass in mock dependencies during testing — no hardcoded logic!

---

## ✅ Up Next

With DI under your belt, you’re ready to build **real APIs** with controllers, model validation, and solid error handling.

➡️ [Building RESTful APIs the Right Way →](./building-restful-apis)

Let’s keep building clean, powerful ASP.NET Core apps 👊

