πŸ”„ ASP.NET Core Application Lifecycle: A Behind-the-Scenes Tour

 

nderstanding the ASP.NET Core lifecycle is critical if you want to build efficient, scalable, and maintainable web applications. From app startup to handling each HTTP request, ASP.NET Core gives you fine control over how your application behaves.

In this post, we’ll explore:

  • πŸ“Œ What the application lifecycle is
  • πŸ›  Startup process: Program.cs and Startup.cs
  • 🌐 Middleware pipeline and request handling
  • πŸ” Dependency Injection and Service Lifetime
  • 🧼 Application shutdown lifecycle

🧠 What Is the Application Lifecycle?

The ASP.NET Core lifecycle refers to the flow of an application from:

  1. Application startup
  2. Request processing
  3. Service instantiation
  4. Response generation
  5. Application shutdown

This cycle ensures your app is properly configured, requests are handled efficiently, and resources are cleaned up.


πŸš€ Application Startup

The startup process in ASP.NET Core happens in the Program.cs file (and formerly also Startup.cs).

πŸ“ Program.cs (ASP.NET Core 6+)

csharp


var builder = WebApplication.CreateBuilder(args);

 

// Configure services

builder.Services.AddControllers();

builder.Services.AddDbContext<AppDbContext>();

 

var app = builder.Build();

 

// Configure middleware

app.UseRouting();

app.UseAuthorization();

app.MapControllers();

 

app.Run();

Think of Program.cs as the bootstrapper of your app — it builds the application host, registers services, and wires up middleware.


🧱 Middleware Pipeline

ASP.NET Core uses a middleware pipeline to process HTTP requests. Each middleware can:

  • Inspect/modify the request
  • Pass control to the next middleware (await next())
  • Handle/modify the response

Example Pipeline Flow:

csharp

app.UseMiddleware<RequestLoggingMiddleware>();  // Logs incoming requests

app.UseRouting();                               // Determines endpoint

app.UseAuthorization();                         // Checks auth rules

app.MapControllers();                           // Executes controller action

Order matters: Each middleware component runs in the order it’s added.


πŸ§ͺ Request Processing Lifecycle

Here's what happens when an HTTP request hits your ASP.NET Core app:

  1. Kestrel Server receives the request.
  2. ASP.NET Core creates an HttpContext object.
  3. The request enters the middleware pipeline.
  4. Routing middleware finds the matching endpoint.
  5. Dependency Injection resolves the required controller and services.
  6. The controller action is executed.
  7. The response travels back through middleware.
  8. The result is sent back to the client.

πŸ”„ Dependency Injection (DI) Lifecycle

ASP.NET Core is built with DI in mind. Services are registered with different lifetimes:

Lifetime

Description

Singleton

One instance for the whole app lifetime

Scoped

One instance per HTTP request

Transient

A new instance every time it's requested

csharp

builder.Services.AddSingleton<IMySingletonService, MyService>();

builder.Services.AddScoped<IMyScopedService, MyService>();

builder.Services.AddTransient<IMyTransientService, MyService>();

Choose the right lifetime to avoid memory leaks or service conflicts.


πŸ“¦ Application Configuration Flow

Program.cs Order of Execution:

  1. WebApplication.CreateBuilder() → sets up config, logging, DI
  2. builder.Services → register services
  3. builder.Build() → builds the web host
  4. Middleware pipeline setup
  5. app.Run() → starts listening for requests

Older Style (Startup.cs):

If using ASP.NET Core 3.1/5.0:

csharp

public class Startup

{

    public void ConfigureServices(IServiceCollection services) { }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { }

}


🧼 Application Shutdown

ASP.NET Core handles shutdown gracefully:

  • Cancels hosted services
  • Disposes of DI-scoped objects
  • Logs shutdown events

Graceful Cleanup Example

csharp

public class CleanupHostedService : IHostedService, IDisposable

{

    public Task StartAsync(CancellationToken cancellationToken)

    {

        Console.WriteLine("App starting...");

        return Task.CompletedTask;

    }

 

    public Task StopAsync(CancellationToken cancellationToken)

    {

        Console.WriteLine("App stopping...");

        return Task.CompletedTask;

    }

 

    public void Dispose()

    {

        Console.WriteLine("Cleanup resources...");

    }

}


🧭 Lifecycle Summary

Phase

Responsibility

Startup

Configure services and middleware

Request Handling

Build HttpContext and run middleware pipeline

Controller Action

Execute logic with DI-injected services

Response

Return result back to client

Shutdown

Dispose services and resources gracefully


⚙️ Tools to Monitor Lifecycle

  • Serilog / NLog: Log app start/stop and requests
  • Middleware: Track requests/responses
  • MiniProfiler: Measure lifecycle performance

🧠 Final Thoughts

Understanding the ASP.NET Core lifecycle helps you:

Register services properly
Control request processing
Handle edge cases like cleanup and shutdown
Debug and optimize performance

 

Comments

Popular posts from this blog

Scrutor the built-in Dependency Injection (DI)

πŸ§… Understanding the Onion Architecture: A Clean Approach to Building Scalable Applications

πŸ”Œ Extension Methods in C#: Power Up Your Code Without Modifying It

Understanding Dependency Injection: A Modern Guide for Developers

🌐 CORS in .NET Explained: Solving the Cross-Origin Problem Like a Pro

πŸ” JWT (JSON Web Token) Explained: Secure Your APIs the Modern Way

πŸ—‚️ DROP vs DELETE vs TRUNCATE in SQL: What’s the Difference?

Ensuring Data Integrity: The Backbone of Reliable Systems

πŸ”— SQL JOINs Explained: Mastering Table Relationships

πŸ›‘️ SIEM Logs Explained: How to Build Secure and Auditable .NET Apps