Chain of Responsibility: Processing Pipelines
Chain of Responsibility: Processing Pipelines
The Chain of Responsibility Pattern is a behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.
๐๏ธ The Problem
Imagine you are building a Web Server. Every incoming request needs to pass through multiple stages: Authentication, Logging, Validation, and Caching. If you hardcode this sequence, itโs hard to change the order or add new steps without modifying the serverโs core code.
๐ The .NET Implementation
In .NET, this pattern is the foundation of Middlewares in ASP.NET Core.
1. The Handler Interface
public abstract class RequestHandler
{
protected RequestHandler Next;
public void SetNext(RequestHandler next) => Next = next;
public abstract void Handle(HttpRequest request);
}2. Concrete Handlers
public class AuthHandler : RequestHandler
{
public override void Handle(HttpRequest request)
{
Console.WriteLine("[AUTH]: Authenticating request...");
if (!request.IsAuthenticated) return; // Stop the chain!
Next?.Handle(request);
}
}
public class LoggingHandler : RequestHandler
{
public override void Handle(HttpRequest request)
{
Console.WriteLine("[LOG]: Logging request details...");
Next?.Handle(request);
}
}๐ ๏ธ Real-World Usage (Client)
var auth = new AuthHandler();
var logging = new LoggingHandler();
// Create the chain: Auth -> Logging
auth.SetNext(logging);
// Process the request
auth.Handle(new HttpRequest { IsAuthenticated = true });๐ก Why use Chain of Responsibility?
- SRP (Single Responsibility): Each handler does exactly one thing.
- OCP (Open/Closed Principle): You can add new handlers without changing existing code.
- Dynamic Chains: You can change the order or composition of the chain at runtime.
- Control Flow: A handler can choose to โshort-circuitโ the request and stop the chain (like the
AuthHandler).