Course contentsShow
← C#
Lesson 239 of 1,9082. Object-Oriented Design in C#Free lesson

Middleware Pipelines

You will construct chain-of-responsibility middleware to process request/response cycles.

Middleware Pipelines: Orchestrating the Request Flow

In this lesson, you will learn how to structure a chain of independent components that inspect or modify data as it passes through your system.

The Chain of Responsibility

Think of a middleware pipeline like an airport security checkpoint. When you (the "Request") travel through the terminal, you pass through a series of stations: metal detector, baggage scan, and passport control. Each station decides whether to let you pass to the next one or stop you entirely if a problem is detected.

In C#, we implement this using the Chain of Responsibility pattern. Each middleware component receives a request, performs its specific logic, and then invokes the "next" component in the sequence. Once the final component finishes, the response travels back up the chain, allowing each piece of middleware to perform cleanup or wrap the result.

The Pipeline Structure

To build this, we define a delegate (or an interface) that represents the "next" step in the chain.

public delegate Task RequestDelegate(HttpContext context);

public class LoggingMiddleware
{
    private readonly RequestDelegate _next;

    public LoggingMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine("Pre-processing: Logging request...");
        
        // Pass control to the next middleware
        await _next(context);
        
        Console.WriteLine("Post-processing: Request completed.");
    }
}

By nesting these components, we create a "Russian Nesting Doll" effect. If you have three middleware components, the execution path looks like this:

  1. Middleware A starts -> calls Middleware B
  2. Middleware B starts -> calls Middleware C
  3. Middleware C performs work
  4. Middleware B resumes and finishes
  5. Middleware A resumes and finishes

This design allows you to add features like authentication, error handling, or compression to your application without cluttering your core business logic. You can simply "plug in" or "remove" components from the pipeline at runtime, keeping your architecture modular and highly maintainable.

Key Takeaway: Middleware pipelines allow you to wrap application logic in a chain of reusable components where each link can perform work before or after the next link in the sequence.