Using F# with .NET Core
Update: The examples in this post used the project.json tooling. for information about using the newer fsproj, see this blog post.
.Net Core was released a few months ago and since then they have released just an update (1.0.1). Its still early days but even though the platform is still at it’s infancy, It’s been gaining momentum.
In the past series of blog post, I examined building applications with F# using the regular .Net Framework. The sample application Dumia had reached prototype stage but I wasn’t happy with the web development experience from a Pure F# perspective and had to make architectural sacrifices. I also couldn’t figure out an easy way to do database migrations without having to type everything from scratch.
This was around the time .NET Core tools were in development so I decided to jump on the bleeding edge. After all.. what could possibly go wrong? *smile*.
Anyway, from the little I played around with, I quickly realized that the personality and design of .NET Core better suits F# development. The fact that they detached “the tooling” from “the editing” (Visual Studio) means that it levels the playing field across all of the dotnet ecosystem and the CLR is much less “C# Language Runtime” and more “Common Language Runtime”
I was so excited and pumped that I’ve decided to port the existing Dumia Prototype to .NET Core using F# exclusively (Almost.. Technically Razor Templates are C#). The Project Manager in me cringes at the thought of changing technology in the middle of a project, especially one that just got released. But I’m doing this because in my mind, the Pros are much greater than the Cons and hopefully, this will serve as a blueprint for my future projects.
Let’s Do This!
I knew before I could start the port, I needed to know that I could tackle these three scenarios using .NET Core
- Creating Web Applications
- Creating and Referencing Class Libraries
- Data Access (Including Database Migration Strategy)
Getting Started
First you need to download and install the Tools. Head over to dot.net/core and follow the instructions. Its the same for Windows, Mac and Linux. The only thing you’d do differently is to use the F# Language switch.
As for Editors/IDEs, Currently VSCode is the editor with the most .NET Core support. Everything is cross-platform and free so bring your Macs and Linux Machines along.
Here are the full instructions
Creating Web Applications
In .NET Core web applications are just console applications that host a Webserver inside them just like Ruby’s Rack or NodeJS. All you need to do is add the necessary packages and you are off to the races.. Except that its a lot of boiler plate to write. Thankfully, there are now yeoman generators available for these. Just install NodeJS (You’ll need it anyway to do front end work) and then run
npm install -g yo generator-aspnet
After that all you need to do is enter yo aspnet in the command line and you’ll see a kind of Command Line Interface you can use to pick the project type you want.. kind of like File > New Project. Something like this
The yeoman generator for ASP.NET currently supports scaffolding .NET Core F# Projects. In addition, there are plugins for VS Code and Atom so that you don’t need to type the commands yourself.
Creating and Referencing Class Libraries
Now that we have the ability to create and run web applications, the next step is layering and project separation.
In theory, a .NET Core dependency is just a dependency so the project doesn’t care if it depends on a Nuget Package or Source Folder. Its transparent to the build system. The beauty of this is that you could download the source for a Nuget Package and compile/debug against that without touching your code, which is pretty neat.
However you might want to restrict dependency to the Project Folder of dependent libraries. For this, all you need to do is create the project in the adjacent to the current project and and add the following line
“Project.Library”: { “target”: “project” }
This tells the .NET Core run-time to depend directly on the project folder adjacent to the current project. Technically, it could be anywhere on your machine, all you need to do is add the location to a global.json file
Data Access (Including Database Migration Strategy)
Data Access is an area of strength for F#. Type Providers are the idiomatic way to get access to data from F# and they are totally awesome.
However, when it comes to having managing changes over time to the schema of the database, There isn’t a good, easy way to do so. This is an example of an area where even though C# isn’t as good, the tooling helps give a better overall experience. Using C#, the tooling (typically Visual Studio) could look at you data access objects and create what is essentially a migration script but in code which you can check in to source control and at runtime the application can upgrade the database by itself. This saves you from mucking about with server credentials and writing update schemas. Unfortunately, this workflow hasn’t supported F# projects in the past.
To be clear, There are libraries like the Fluent Migrator that you could use. but you’d have to write the migration scripts in code by hand. Aside from being tedious initially, computing diffs between migrations is error prone if done by hand. Not to mention that it hasn’t been ported to .NET Core. Which leaves us with one option..
Entity Framework Core
Entity Framework Core is a complete rewrite from scratch of the popular Entity Framework or as it’s affectionately called “Entity Framework Magic Unicorn Edition”. I could go on and on but the key takeaway is that it’s tooling doesn’t depend on Visual Studio anymore.
To figure out how this would work with F#, I took Julie Lerman’s course on Pluralsight (Play by Play: EF Core 1.0: First Look) but the twist was to try and do everything using only F#. I sensed that it would be a difficult undertaking and so that I couldn’t talk myself out of it, I tweeted
She was kind enough to respond (which blew my mind btw) and I promised that I would create an FSharp equivalent of her demo code and send her a pull request.
And boy was I in for a wild ride! Yes a lot of it went as expected. However, migrations were a bit tricky as the tool would emit C# code and I had to convert them by hand to F#. I also ran into problems trying to use quotations, I had to import a library and then trick the .NET core runtime to accept portable class libraries… and later realized that the F# compiler can automatically convert F# function expressions (fun x -> x.id) into Expression<Func<T>> just like C#.
After that huddle, I was able complete the translation of the migration code and execute it against the database. Here is a sample of the migration. Full source is available here
Verdict
All in all, my experience with .NET Core has been exciting. I hope, I’ve been able to show that all the tools are in place to build real world applications using F# and .NET Core and I’m also excited for the future of the platform. A good size of the F# community isn’t eager to make the jump yet (and for good reason) but the support is growing.