ASP.NET Core Web API

Dependency Injection (DI) Deep Dive

1 Views Updated 5/4/2026

Dependency Injection (DI) Deep Dive

ASP.NET Core was fundamentally built around Dependency Injection (DI). It is not an add-on; it is the core engine that powers the framework. DI provides Inversion of Control (IoC), allowing classes to declare what they need (Interfaces) without concerning themselves with how to build it.

1. The Anti-Pattern: Tight Coupling

❌ Why the `new` keyword is toxic in Controllers
public class PaymentController : ControllerBase
{
    public IActionResult Process()
    {
        // ❌ TIGHT COUPLING! 
        // 1. If StripePaymentService's constructor changes, this code breaks.
        // 2. This code physically cannot be unit tested without hitting the real Stripe API.
        var paymentService = new StripePaymentService(); 
        paymentService.ChargeCard();
    }
}

2. Constructor Injection (The Solution)

Instead of manually constructing nested dependencies, we use the Built-in IoC Container inside Program.cs.

// 1. Define the capabilities (Contract)
public interface IPaymentProcessor
{
    bool ChargeCard(decimal amount);
}

// 2. Create the Implementation
public class StripePaymentProcessor : IPaymentProcessor
{
    public bool ChargeCard(decimal amount) { return true; /* Contacts Stripe Hub */ }
}

// 3. Register it in Program.cs
// "Whenever a class asks for an IPaymentProcessor, give it a StripePaymentProcessor."
builder.Services.AddScoped<IPaymentProcessor, StripePaymentProcessor>();

// 4. Consume it in the Controller
public class PaymentController : ControllerBase
{
    private readonly IPaymentProcessor _paymentProcessor;

    // The framework magically provides the instance!
    public PaymentController(IPaymentProcessor paymentProcessor)
    {
        _paymentProcessor = paymentProcessor;
    }
}

3. Service Lifetimes Explained

When you register a service in builder.Services, you must dictate its memory lifespan. Choosing the wrong lifetime causes catastrophic Data Leaks (Capitive Dependencies).

LifetimeSyntaxWhen is it created?Memory Danger
TransientAddTransient()Creates a brand new instance every single time it is requested.High RAM/Garbage Collector usage objects are expensive to create.
ScopedAddScoped()Creates one instance per HTTP Request. Shared across all services during that specific API call.The absolute safest choice for almost everything (e.g., DbContext).
SingletonAddSingleton()Created once at app startup. All users concurrently share the exact same object in RAM.Extreme danger of Multi-threading collisions and memory leaks. Use only for stateless helper caches.

4. Interview Mastery

Q: "What is a Captive Dependency in ASP.NET Core?"

Architect Answer: "A captive dependency occurs when a service with a longer lifetime holds a service with a shorter lifetime hostage. The most common/fatal example is injecting a Scoped service (like EF Core DbContext) into a Singleton service. Because the Singleton is created once on app startup and never destroyed, the DbContext injected into it is also never destroyed. This DbContext will slowly eat RAM for days, track every entity ever queried, and eventually crash the server with an OutOfMemoryException. ASP.NET Core has a built-in validation feature (ValidateScopes) that will actually crash the app on startup if you attempt this to protect you."

ASP.NET Core Web API
1. Fundamentals & HTTP
Introduction to ASP.NET Core Web API REST Principles and HTTP Methods Controllers & ControllerBase Routing (Attribute vs Conventional) Action Return Types (IActionResult)
2. Request Handling
Model Binding (FromQuery, FromBody, FromRoute) Dependency Injection (DI) Deep Dive App Settings & The Options Pattern
3. Data Access & Architecture
EF Core Setup in Web API DbContext & Migrations Repository & Unit of Work Pattern Asynchronous Programming (async/await)
4. Data Transfer & Validation
Data Transfer Objects (DTOs) & AutoMapper Model Validation (DataAnnotations) FluentValidation Integration
5. Advanced Concepts
Global Exception Handling Middleware Content Negotiation (JSON vs XML) Pagination & Filtering Advanced Searching & Sorting HATEOAS (Hypermedia) Implementation Output Caching & Response Caching
6. Security & Authorization
Cross-Origin Resource Sharing (CORS) JWT Authentication Setup Access Tokens & Refresh Tokens Workflow Role-Based & Policy-Based Authorization API Key Authentication Rate Limiting & Throttling
7. Documentation & Testing
Swagger & OpenAPI Configuration Customizing API Documentation Unit Testing Controllers (xUnit & Moq) Integration Testing (WebApplicationFactory)
8. Microservices & Deployment
Consuming External APIs (IHttpClientFactory) Health Checks & Diagnostics API Versioning Strategies Deploying APIs (Docker & Azure)