I have become increasingly more interested in F# and hope, someday, to transition over from C# to F# in my day-to-day work. (More on that later.)
I have also become increasingly more interested in Simple.Web by Mark Rendle and hope, someday, to transition over from ASP.NET MVC to Simple.Web in my day-to-day work. (More on that later, as well.)
Given both my fondness of F# and Simple.Web, I decided to try to marry the two. I created the normal ASP.NET Empty Project and added the Simple.Web.Aspnet NuGet package along with the Simple.Web.Razor NuGet package. Then I created a handlers project (F# Class Library), referenced it from the first project, and added the same NuGet package. I created a simple handler for the site's index in the first project.
namespace SimpleTest.Web open Simple.Web [<UriTemplate("/")>] type Class1() = interface IGet with member this.Get() = Status.OK
I also added a Razor page to handle my get request and then hit F5 to fire it up. Since it was so simple, I was expecting to see my fake homepage and see my little test succeed. Wrong.
Instead, I am greeted with a yellow screen of death telling me "Object reference not set to an instance of an object." Hmmm...
I created the same class in C# and everything worked fine. I was beginning to wonder if this was going to work out at all. Well, after some fiddling, I got it to work. Why it works, I am not really sure about. (I'm far from completely comfortable in F#, let alone an expert.) All I had to do was add a member function that mirrored my interface version of Get().
namespace SimpleTest.Web open Simple.Web [<UriTemplate("/")>] type Class1() = member this.Get() = Status.OK interface IGet with member this.Get() = Status.OK
Of course that means I can just return the result of the member function from the interface implementation. But, that got me to thinking. I decided, in the interface implementation, to throw a NotImplementedException:
namespace SimpleTest.Web open System open Simple.Web [<UriTemplate("/")>] type Class1() = member this.Get() = Status.OK interface IGet with member this.Get() = raise(new NotImplementedException())
To my amusement, it still loaded my page. I understand that to access an interface-defined method in F# you have to explicitly cast the instance to the interface you're targeting. I just did not know that applied across the language boundaries as well when doing whatever magic Simple.Web is doing to find the applicable method.
Time to hunt that down next.