MiddlewareGraph 1.0.0

dotnet add package MiddlewareGraph --version 1.0.0
                    
NuGet\Install-Package MiddlewareGraph -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MiddlewareGraph" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MiddlewareGraph" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="MiddlewareGraph" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MiddlewareGraph --version 1.0.0
                    
#r "nuget: MiddlewareGraph, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MiddlewareGraph@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MiddlewareGraph&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=MiddlewareGraph&version=1.0.0
                    
Install as a Cake Tool

MiddlewareGraph

ASP.NET Core Middleware Pipeline Visualizer & Inspector

NuGet License: MIT

MiddlewareGraph gives you complete visibility into your ASP.NET Core middleware pipeline. No more guessing what middleware is registered, in what order, or how long each one takes.

The Problem

ASP.NET Core's middleware pipeline is completely opaque:

  • Zero visibility — No way to see the ordered middleware list without reading every line of Program.cs
  • No isolation testing — Testing a single middleware requires spinning up a full TestServer
  • No latency observability — Cannot see per-middleware execution time without custom wrappers
  • Silent ordering bugs — Putting Authentication after Authorization silently breaks security
  • Third-party black boxes — NuGet packages register middleware invisibly

Features

Feature Description
Pipeline Introspection See every middleware in order with type, assembly, and category
Debug Dashboard Interactive HTML dashboard at /middlewaregraph
Per-Middleware Latency P50/P95/P99 timing per middleware with ring buffer
Ordering Validation Catch Auth-before-AuthZ bugs at startup
Test Harness Test any middleware in isolation — no TestServer needed
Request Flow Tracing X-MiddlewareGraph-Trace header shows request path
Pipeline Diff Compare middleware across environments
Health Checks ASP.NET Core health check integration
Mermaid/PlantUML Export Generate architecture diagrams automatically
Startup Time Breakdown See which middleware registration is slow

Quick Start (5 lines)

// Program.cs
builder.Services.AddMiddlewareGraph();

var app = builder.Build();
app.UseMiddlewareGraph(); // Add before other middleware
// ... rest of your pipeline

Visit https://localhost:5001/middlewaregraph to see the dashboard.

Installation

dotnet add package MiddlewareGraph

Full Configuration

builder.Services.AddMiddlewareGraph(options =>
{
    // Dashboard
    options.Dashboard.Path = "/middlewaregraph";
    options.Dashboard.Enabled = true;

    // Metrics — per-middleware latency tracking
    options.Metrics.Enabled = true;
    options.Metrics.RingBufferSize = 128;

    // Validation — catch ordering bugs at startup
    options.Validation.ThrowOnViolation = true;
    options.Validation.Rules.RequireBefore<AuthenticationMiddleware, AuthorizationMiddleware>();

    // Diagnostics — request flow tracing
    options.Diagnostics.EnableRequestTracing = true;
});

API Reference

Querying the Pipeline

Inject IMiddlewareGraph anywhere:

public class MyService(IMiddlewareGraph graph)
{
    public void Inspect()
    {
        // All registered middleware in order
        var all = graph.Pipeline;

        // Find specific middleware
        var auth = graph.Find<AuthenticationMiddleware>();

        // Check ordering
        bool valid = graph.IsBefore<CorsMiddleware, RoutingMiddleware>();

        // Get branches (from app.Map())
        var branches = graph.GetBranches();

        // Total count
        int count = graph.Count;
    }
}

Middleware Test Harness

Test any middleware in isolation — no TestServer, no WebApplicationFactory:

// Minimal test
var result = await MiddlewareTestHarness
    .For<MyCustomMiddleware>()
    .Build()
    .SendAsync(HttpMethod.Get, "/test");

// Full test with DI and request configuration
await using var runner = MiddlewareTestHarness
    .For<MyCustomMiddleware>()
    .WithServices(services =>
    {
        services.AddSingleton<IMyDependency, MockDependency>();
    })
    .WithRequest(ctx =>
    {
        ctx.Request.Method = "POST";
        ctx.Request.Path = "/api/orders";
        ctx.Request.Headers["X-Tenant-Id"] = "tenant-123";
    })
    .WithNext(ctx =>
    {
        ctx.Response.StatusCode = 200;
        return Task.CompletedTask;
    })
    .Build();

var context = await runner.SendAsync();
Assert.Equal(200, context.Response.StatusCode);
Assert.True(context.Response.Headers.ContainsKey("X-Processed-By"));

Test short-circuiting:

await using var runner = MiddlewareTestHarness
    .For<AuthMiddleware>()
    .WithRequest(ctx => ctx.Request.Path = "/blocked")
    .WithPassthroughNext()
    .Build();

var context = await runner.SendAsync();
Assert.Equal(403, context.Response.StatusCode);

Ordering Validation

Built-in rules catch common mistakes:

  • Authentication must come before Authorization
  • CORS must come before Routing
  • Routing must come before Endpoints
  • ExceptionHandler should be early in the pipeline
  • HTTPS Redirection should be early in the pipeline

Add custom rules:

options.Validation.Rules
    .RequireBefore<CorsMiddleware, RoutingMiddleware>()
    .MustBeFirst<ExceptionHandlerMiddleware>()
    .MustBeLast<EndpointMiddleware>();

Health Checks

builder.Services.AddHealthChecks()
    .AddMiddlewareGraphHealth(options =>
    {
        options.DegradedThreshold = TimeSpan.FromMilliseconds(100);
        options.UnhealthyThreshold = TimeSpan.FromMilliseconds(500);
    });

Pipeline Diff

Compare middleware across environments:

// Save a snapshot (via /middlewaregraph/snapshot endpoint or programmatically)
var snapshot = PipelineSnapshot.Create(graph.Pipeline, "Production");

// Compare two snapshots
var diff = PipelineDiff.Compare(devSnapshot, prodSnapshot);
Console.WriteLine($"Added: {diff.Added.Count}");
Console.WriteLine($"Removed: {diff.Removed.Count}");
Console.WriteLine($"Reordered: {diff.Reordered.Count}");
Console.WriteLine($"Identical: {diff.AreIdentical}");

Export to Mermaid/PlantUML

// Generate Mermaid diagram for GitHub markdown
string mermaid = graph.ExportMermaid();

// Generate PlantUML diagram
string plantuml = graph.ExportPlantUml();

Or visit:

  • /middlewaregraph/mermaid — Mermaid flowchart syntax
  • /middlewaregraph/plantuml — PlantUML activity diagram

Dashboard Endpoints

Endpoint Description
GET /middlewaregraph Interactive HTML dashboard
GET /middlewaregraph/json Pipeline as JSON
GET /middlewaregraph/metrics Per-middleware latency metrics
GET /middlewaregraph/mermaid Mermaid diagram export
GET /middlewaregraph/plantuml PlantUML diagram export
GET /middlewaregraph/snapshot Pipeline snapshot for diffing
GET /middlewaregraph/startup Startup registration timings

Dashboard Preview

┌─────────────────────────────────────────────────┐
│  MiddlewareGraph — Pipeline Inspector            │
│  Pipeline | Metrics | Validation | Startup       │
├─────────────────────────────────────────────────┤
│                                                  │
│  Middleware Pipeline (8 registered)               │
│  Request flows top → bottom                      │
│                                                  │
│  0  DashboardMiddleware     [Application]        │
│  1  FlowTraceMiddleware     [Application]        │
│  2  HttpsRedirection        [Framework]   0.1ms  │
│  3  Routing                 [Framework]   0.3ms  │
│  4  CustomMiddleware        [Application] 0.05ms │
│  5  Authentication          [Framework]   1.2ms  │
│  6  Authorization           [Framework]   0.8ms  │
│  7  Endpoints               [Framework]   2.1ms  │
│                                                  │
│  Validation: ✓ All rules passed                  │
│                                                  │
│  Export: [JSON] [Mermaid] [PlantUML] [Snapshot]  │
└─────────────────────────────────────────────────┘

Technical Details

  • Zero external dependencies — Only Microsoft.AspNetCore.App framework reference
  • Zero reflection at request time — Reflection only during startup for name extraction
  • Thread-safe metrics — Lock-free ring buffer using Interlocked operations
  • Dashboard: pure HTML+CSS — No JavaScript frameworks
  • Negligible overhead — ~450ns per request for timing (15 middleware × 30ns each)
  • Dev-only by default — Dashboard only serves in Development environment

Architecture

MiddlewareGraph uses an IStartupFilter to wrap the IApplicationBuilder with an instrumenting decorator. Every Use() call is intercepted to:

  1. Extract the middleware type name via reflection on the delegate closure
  2. Classify it as Framework/ThirdParty/Application based on assembly
  3. Wrap the delegate with Stopwatch timing
  4. Record the descriptor in the pipeline graph

The pipeline graph is frozen after startup and exposed as a singleton IMiddlewareGraph via DI.

Comparison

Feature MiddlewareGraph MiddlewareAnalysis Manual
Pipeline visualization ✅ HTML Dashboard
Per-middleware latency ✅ P50/P95/P99 Custom code
Ordering validation ✅ Built-in + custom
Isolation test harness ✅ Fluent API TestServer
Request flow tracing ✅ Response header DiagnosticSource Custom
Pipeline diff ✅ Cross-environment
Mermaid/PlantUML export
Health checks
External dependencies None None N/A

License

MIT

Version History

  • v1.0.0 — Initial release: Pipeline introspection, dashboard, latency tracking, test harness, ordering validation, request tracing, pipeline diff, health checks, Mermaid/PlantUML export, startup timing
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 44 3/29/2026