Thanks all for the great response on the first blog post! My phone was pinging with retweets for two days. Very encouraging!

So let's start on the topic for the day, and it's a huge one: IBuilder

The IBuilder interface has a very specific purpose. It's passed from the hosting program to your Startup class's Configure method. This method is expected to call IBuilder extension methods repeatedly which adds components to the request pipeline. Most of these extension methods will boil down to a call to IBuilder.Use.

Let's take a look at the smallest possible web application that uses it.

project.json

{
    "dependencies": {
        "Microsoft.AspNet.Server.WebListener": "0.1-alpha-*"
    },
    "commands":{
        "web" : "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000/"
    }
}

Startup.cs

using Microsoft.AspNet.Builder;

public class Startup  
{
    public void Configure(IBuilder app)
    {
        app.Run(async context =>
        {
            context.Response.ContentType = "text/plain";
            await context.Response.WriteAsync("Hello World!");        
        });
    }
}

If you'd like you can get and run this source by running the following from the command-line.

git clone https://github.com/loudej/WheresLouSamples  
cd WheresLouSamples\02.Builder  
go  

When you see the line saying "Started" point a browser at http://localhost:5000/

Hello World

The new HttpContext, HttpRequest and HttpResponse are all defined as abstract classes in the Microsoft.AspNet.Http NuGet package assembly. These types are designed to work the same on IIS and when you're self-hosted, and are intended to be instantiatable if you're writing unit tests. The implementations used are available in Microsoft.AspNet.PipelineCore if you need to instantiate them directly.

The idea of the request actually exist in two layers. There's the abstract HttpContext/HttpRequest/HttpResponse application-facing layer your program and web frameworks will work with. There's also a lower interface-based layer that http servers like Helios/IIS and WebListener work with as they raise requests up to the pipeline. We can talk about that more if you're interested, but I don't want to follow that tangent in this article.

The app.Run you see in this sample is actually an extension method on IBuilder. It accepts the request handler which is a function that is called with an HttpContext once for every request that arrives.

If app.Run is an extension method, what's the actual method?

The actual method that Run and all middleware call is IBuilder.Use. The Use method is actually a lot like the Run method but it has one more feature to it: it will pass next a next function to the request handling component. This is what should be called via await next(context); to pass control to the remaining components in the pipeline.

Here's the basic footprint of calling IBuilder.Use with inline code:

app.Use(next => async context =>  
{
    // incoming code goes here
    await next(context);
    // outgoing code goes here
});

The double-lambda might look odd but it's not doing anything magical. When the pipeline is being build it calls the first lambda where the next function is passed in and the request handler is returned. The returned handler is then called once per request. In the example above the next is closed over and invoked to continue execution.

If you prefer a more object-oriented look to your middleware then there's a standard way you can arrange this code as a class.

public class SampleMiddleware  
{
    RequestDelegate _next;

    public SampleMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // incoming code goes here
        await _next(context);
        // outgoing code goes here
    }
}

One way to add this type of class the pipeline is to instantiate it from the correct place and return a reference to its Invoke method.

  app.Use(next => new SampleMiddleware(next).Invoke);

That doesn't look nice though, so what you probably want to do instead is add it using the app.UseMiddleware extension method. It's available in the Microsoft.AspNet.RequestContainer nuget package. (That's a pretty bad name, so expect it to change...)

    "dependencies": {
        "Microsoft.AspNet.Server.WebListener": "0.1-alpha-*",
        "Microsoft.AspNet.RequestContainer": "0.1-alpha-*"
    },

So you can then put the SampleMiddleware in place with the much cleaner looking:

  app.UseMiddleware<SampleMiddleware>();
  // or
  app.UseMiddleware(typeof(SampleMiddleware));

That said, it's even more likely if you're going to be creating a middleware class that you'll also be adding an extension method to IBuilder. Extension methods are more discoverable, and also provide intellisense, overloading, and a place to put doc-comments for any arguments you may need to pass into the middleware instance.

public static class SampleBuilderExtensions  
{
    public static IBuilder UseSample(this IBuilder app)
    {
        return app.UseMiddleware<SampleMiddleware>();
    }
}

//... usage ...
    app.UseSample();

Order is important

The middleware have an order of execution which flows along calls to their next delegate, which is passed to them at startup. That order is entirely determined by the order they are IBuilder.Use()'ed, so the order that middleware are added to the pipeline is critical. It determines the order that components have control as the request passed through the system.

You would add a diagnostics error page first, for example, because you want to see a friendly error page for exceptions thrown from any component. You would also add authentication middleware before any framework middleware because the authenticated user needs to be in effect before they execute. If you have a custom 404 page that should be added last, because you only want it to have control if all of the middleware have decided to allow the execution to pass along to the next hop to write the response.

There's an example of the order of execution illustrated with console output. Three middleware in a row each write a line on the way in and again on the way out. To see this run, paste the following into a command prompt:

git clone https://github.com/loudej/WheresLouSamples  
cd WheresLouSamples\03.Builder  
go  

And the full text of that example looks like this

using System;  
using System.Diagnostics;  
using System.Threading;  
using System.Threading.Tasks;  
using Microsoft.AspNet.Builder;  
using Microsoft.AspNet.Http;

public class Startup  
{
    public void Configure(IBuilder app)
    {
        // inline middleware via Use
        var requestCount = 0;
        app.Use(next => async context =>
        {
            var sw = new Stopwatch();
            sw.Start();
            var requestNumber = Interlocked.Increment(
                ref requestCount);

            // request is incoming
            Console.WriteLine(string.Format(
                "1st #{0} incoming {1} {2}{3}{4}", 
                requestNumber,
                context.Request.Method,
                context.Request.PathBase,
                context.Request.Path,
                context.Request.QueryString));

            // pass control to following components
            await next(context);

            // call is unwinding
            Console.WriteLine(string.Format(
                "1st #{0} outgoing {1} {2}ms", 
                requestNumber,
                context.Response.StatusCode,
                sw.ElapsedMilliseconds));
        });

        // middleware class via use
        app.Use(next => 
            new LogRequestsMiddleware(next, "2nd").Invoke);

        // middleware class via extension method
        app.UseLogRequests("3rd");

        // finally, respond to all requests in the same way
        app.Run(async context =>
        {
            context.Response.ContentType = "text/plain";
            await context.Response.WriteAsync("Hello World!");        
        });
    }
}

public static class LogRequestsExtensions  
{
    public static IBuilder UseLogRequests(this IBuilder app, string label)
    {
        // additional arguments are passed to constructor
        return app.UseMiddleware<LogRequestsMiddleware>(label);
    }
}

public class LogRequestsMiddleware  
{
    RequestDelegate _next;
    int _requestCount;
    string _label;

    // called once when pipeline is built
    public LogRequestsMiddleware(RequestDelegate next, string label)
    {
        _next = next;
        _label = label;
    }

    // called once per request
    public async Task Invoke(HttpContext context)
    {
        var sw = new Stopwatch();
        sw.Start();
        var requestNumber = Interlocked.Increment(
            ref _requestCount);

        // request is incoming
        Console.WriteLine(string.Format(
            "{0} #{1} incoming {2} {3}{4}{5}", 
            _label,
            requestNumber,
            context.Request.Method,
            context.Request.PathBase,
            context.Request.Path,
            context.Request.QueryString));

        // pass control to following components
        await _next(context);

        // call is unwinding
        Console.WriteLine(string.Format(
            "{0} #{1} outgoing {2} {3}ms", 
            _label,
            requestNumber,
            context.Response.StatusCode,
            sw.ElapsedMilliseconds));
    }
}