Thoughts, Tips and Tricks on what I'm currently do for a living. Currently most of my spare time is spent on contributing to Akka.NET.

Wednesday, January 30, 2013

Nancy and Owin

This is a short post on how to run NancyFX in an Owin pipeline on a HttpListener Host.

Update

David Fowler (@davidfowl), and an anonymous commenter, pointed out there was a better way to set up Owin hosting. The code has been updated.

Note, before we start. Since HttpListener might require permissions, the easiest way round this is running as an administrator, or starting VS2012 as administrator. You shouldn’t be doing this in production. Configuring HTTP and HTTPS on MSDN.

Create a Console App

Create a Console App and install the following packages in the Package Manager Console. Note that prerelease nuget packages are used.

Install-Package Microsoft.Owin.Host.HttpListener -Pre
Install-Package Microsoft.Owin.Hosting -pre
Install-Package Nancy.Hosting.Owin

These packages will also be installed when the packages above are installed:

Owin, Nancy

The Code

First we need a Nancy Module:

public class SampleModule : NancyModule
{
  public SampleModule()
  {
    Get["/"] = _ => "Hello World!";
  }
}

Then we need to configure the Owin application to run Nancy.

public class Startup
{
  public void Configuration(IAppBuilder app)
  { //Uses an extension method that adds Nancy at the end of an Owin pipeline
    app.RunNancy();  
  }
}

The extension method used to configure the app:

public static class NancyOwinAppBuilderExtensions
{
  public static IAppBuilder RunNancy(this IAppBuilder builder)
  {
    return RunNancy(builder, new DefaultNancyBootstrapper());
  }

  public static IAppBuilder RunNancy(this IAppBuilder builder, INancyBootstrapper bootstrapper)
  {
    var nancyOwinHost = new NancyOwinHost(bootstrapper);
    return RunNancy(builder, nancyOwinHost);
  }

  public static IAppBuilder RunNancy(this IAppBuilder builder, NancyOwinHost host)
  {
    return RunApp(builder, host.ProcessRequest);
  }

  private static IAppBuilder RunApp(IAppBuilder builder, Func<IDictionary<string, object>, Task> app)
  {
    return UseFunc(builder, next => app);
  }

  private static IAppBuilder UseFunc(IAppBuilder builder, Func<Func<IDictionary<string, object>, Task>, Func<IDictionary<string, object>, Task>> middleware)
  {
    return builder.Use((object)middleware, new object[0]);
  }
}

Lastly we put everything together and starts the Owin Server:

class Program
{
  static void Main(string[] args)
  {
    var url = "http://+:8080";

    using (WebApplication.Start<Startup>(url))
    {
      Console.WriteLine("Running on http://localhost:8080", url);
      Console.WriteLine("Press enter to exit");
      Console.ReadLine();
    }
  }
}

That’s it. Hit F5 to run it. Visit http://localhost:8080/ in a browser.

Package versions

The following packages were used in the code.

Microsoft.Owin.Host.HttpListener version=0.18.0-alpha
Microsoft.Owin.Hosting version=0.18.0-alpha

Nancy version=0.15.3
Nancy.Hosting.Owin version=0.15.3
Owin version=1.0

Download code

https://gist.github.com/4676779