Friday, December 20, 2013

Pure F# ASP.NET Web Applications and Simple.Web

So, there has been some awesome work done by Daniel Mohl on a pure F# project for ASP.NET. Unfortunately, I have been spoiled by Simple.Web and wondered if I could make the project work with it. It was not as hard as I thought it would be, at all. Fortunately, Mark Rendle and company have given us the Simple.Web.AspNet NuGet package which makes this trivial.

The biggest hurdle of it all is the NuGet package adds a C# file called OwinAppSetup.cs which sets up the OWIN bindings, on top of which Simple.Web runs. It is a really simple file, actually:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Simple.Web;

namespace FsWebApp
{
    using UseAction = Action<Func<IDictionary<string, object>, Func<IDictionary<string, object>, Task>, Task>>;

    public class OwinAppSetup
    {
        public static void Setup(UseAction use)
        {
            use(Application.Run);
        }
    }
}

Converting this to F# was fairly straight forward and is easily replaced with:

module OwinAppSetup

open System
open System.Collections.Generic
open System.Threading.Tasks
open Simple.Web

type UseAction = Action<Func<IDictionary<string, obj>, Func<IDictionary<string, obj>, Task>, Task>>

type OwinAppSetup() =
    static member Setup(useMethod:UseAction) =
        let run x y = Application.Run(x, y)
        run |> useMethod.Invoke

It is pretty much like the original version except that F#'s type system doesn't let us pass the run method into the UseMethod directly and call it like a method. Instead you have to manually call the Invoke method. (Easy stuff.) Other than deleting a few of the folders from the project template like the Models folder, everything runs perfectly. I also removed a few of the MVC/Web API specific assemblies from the project but that was all that was needed to get going.

Update

There is now some semblance of a Simple.Web F# project template available.