ASP.NET vNext Middleware versus OWIN/Katana Middleware

Per OWIN specification, the application delegate or AppFunc takes the IDictionary environment and returns a Task when it has finished processing. The application delegate is like so.

using AppFunc = Func<
        IDictionary<string, object>, // Environment
                              Task>; // Done

So, a raw OWIN middleware, so to speak, will be this,

Func<AppFunc, AppFunc>

or this, if you are okay with Func all over the place.

Func<Func<IDictionary<string, object>, Task>, 
     Func<IDictionary<string, object>, Task>>

To use a middleware, you will use the Use method defined on the IAppBuilder interface. So, at a basic level, you can have something like this.

using AppFunc = Func<IDictionary<string, object>,Task>;

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var middleware = new Func<AppFunc, AppFunc>(
                            Middleware);
        app.Use(middleware);
    }

    public AppFunc Middleware(AppFunc nextMiddleware)
    {
        AppFunc appFunc =
            (IDictionary<string, object> env) =>
            {
                // Do your middleware thing here ...

                // ... and then call the next one
                return nextMiddleware(env);
            };

            return appFunc;
    }
}

But then, no one writes a middleware like this and an “object-oriented” middleware will be like this.

public class OoMiddleware
{
    private readonly AppFunc next;

    public OoMiddleware(AppFunc next)
    {
        this.next = next;
    }

    public async Task Invoke(
         IDictionary<string, object> environment)
    {
        // Do your middleware thing here ...

        // ... and then call the next one
        await this.next(environment);
    }
}

BTW, the Use method in IAppBuilder specifies object as middleware like so.

IAppBuilder Use(object middleware, 
                     params object[] args);

This is not very helpful in guessing how the middleware should be.

Now, with ASP.NET vNext, things are slightly different. A middleware is still a middleware but there are differences. First of all, there is no IAppBuilder. Instead, there is IApplicationBuilder. IApplicationBuilder’s Use method is like this.

IApplicationBuilder Use(Func<RequestDelegate, 
                          RequestDelegate> middleware);

RequestDelegate is defined like so.

public delegate Task 
            RequestDelegate(HttpContext context);

So, an ASP.NET vNext middleware is Func<RequestDelegate, RequestDelegate> and your Configure method will be like so, for a basic ASP.NET vNext middleware. Note, it is not Configuration.

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(
           new Func<RequestDelegate, RequestDelegate>(
             AspNetVnextMiddleware));
        // Other middleware components go here
    }

    RequestDelegate AspNetVnextMiddleware(
                         RequestDelegate next)
    {
        RequestDelegate rd = (HttpContext ctxt) =>
        {
            ctxt.Response.WriteAsync(
                          "Hello, ASP.NET vNext");
            return next(ctxt);
        };

        return rd;
    }
}

The OO way of writing a middleware in ASP.NET vNext is like this.

public class OoAspNextVnextMiddleware
{
    RequestDelegate next;

    public OoAspNextVnextMiddleware(
                           RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // Do your middleware thing here ...

        // ... and then call the next one
        await this.next(context);
    }
}

So, can we use an OWIN/Katana middleware in ASP.NET vNext? Sure. Say, we have a middleware like this.

public class MyOwinMiddleware
{
    private readonly AppFunc next;

    public MyOwinMiddleware(AppFunc next)
    {
        this.next = next;
    }

    public async Task Invoke(
        IDictionary<string, object> environment)
    {
        // Inbound processing
        await this.next(environment);
        // Outbound processing
    }
}

To use it with ASP.NET vNext, you just need to use the UseOwin extension method in Microsoft.AspNet.Builder (HttpAbstractions), like this.

app.UseOwin(addToPipeline =>
{
    addToPipeline(next =>
        {
            return new MyOwinMiddleware(next).Invoke;
        });
});

PS. With Katana, there are a couple of ways of writing a middleware class: using AppFunc, which is the recommended way and using OwinMiddleware class. Although using OwinMiddleware class is not a recommended practice, even the out-of-box middleware from Katana does use this. But with ASP.NET vNext, all middleware consistently use RequestDelegate and HttpContext.

Advertisements

One thought on “ASP.NET vNext Middleware versus OWIN/Katana Middleware

  1. Do you have a code sample somewhere? (Or do you know where the .UseOwin extension method has moved in beta 4?) I can’t get it to work as of the current beta 4. (It seems this code was written using the alpha 4 release.)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s