Showing Wall-E infront of a yellow VW bus with taxi stripes

I have taken quite a liking into Fabulous - a wrapper around Xamarin.Forms allowing you to write functional UIs with F#. When first looking at the project I noticed that is was being built on AppVeyor and Travis. I asked myself: Why use two CI Systems for compiling one project? After some further digging I found out that there are no hosted macOS Agent on AppVeyor. Travis on the other hand did come with agents for Windows and macOS but did not have the Xamarin Toolchain installed on the agents. Installing the Xamarin Toolchain on every run lead to a build time of over 30 minutes. Since Azure DevOps supports building on Windows and macOS I thought I would give it a go and setup a Pipeline to build Fabulous - I mean how hard can it be? Well hard enough to write a blog post to sum up the steps to get over the pitfalls

TLDR: How to run your FAKE scripts on Azure DevOps

Fabulous uses FAKE to execute the build, tests and create the NuGet packages. FAKE is a power full tool for writing build scripts. FAKE is also a .Net Core CLI tool which is designed for being installed and executed from the command line, so it should be a great fit for running on any build server.

Installing FAKE

Azure DevOps build agents do not come with FAKE preinstalled. Since FAKE is a .Net Core CLI tool this is no problem. The following command should solve this issue:

dotnet tool install fake-cli -g

Unfortunately executing FAKE after installation fails. This is because the installation directory on the Azure DevOps build agents differs from the standard installation location of .Net Core - Why? you ask, well the answer given is security. On Windows we can circumvent this fact by installing FAKE into the Workspace directory:

dotnet tool install fake-cli --tool-path .

Under macOS (and Linux) this approach still fails. The suggested solution is to set DOTNET_ROOT. I ended up with the following lines to be executed on the macOS agent:

export DOTNET_ROOT=$HOME/.dotnet/
export PATH=$PATH:$HOME/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands
dotnet tool install fake-cli -g

On Linux the approach had to adopted again - go figure. I ended up with these lines:

export PATH=$PATH:$HOME/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands
dotnet tool install fake-cli -g

Now you should be able to run your FAKE script on Azure DevOps

Using NuGetFallbackDirectory

This part is not directly related to FAKE but is something I stumbled over while running on Azure DevOps. One test script was referencing the NuGet packages via the global NuGetFallbackDirectory and was looking for them under the default location. Under macOS the location is in the users home directory, so adopting the path as follows did the trick:

let tfsEnvironment = Environment.GetEnvironmentVariable("TF_BUILD")
if (String.IsNullOrEmpty(tfsEnvironment)) then
    let homepath = Environment.GetEnvironmentVariable("HOME")
    Path.Combine(homepath, ".dotnet/sdk/NuGetFallbackFolder")

Note that the variable TF_BUILD is expected to only be set on TFS/VSTS/Azure DevOps. This will allow the script to fall back to the default location should it be executed on a developers machine.

But why even bother?

What is the motivation of migrating from a working CI to another? Are you doing because you are a Microsoft MVP?

These were questions I got when talking with colleagues about my endeavors to build Fabulous on Azure DevOps. I think AppVeyor and Travis are great tools and they have shown that they are up to the task building and testing Fabulous. Other than because I was curious how hard it could be, there were two aspects why I wanted to try to migrate the build to Azure DevOps:

  1. Merging the builds, having two places doing one thing always comes with overhead.
  2. The other one was seeing how much the build time would be reduced by not having to install Xamarin.

So here is a comparison between the build times before and after:

CI PlatformAgent OSBuildTestTime (minutes)
Azure DevOpsmacOS~13-14
Azure DevOpsWindows~6

Now to keep in mind, the build on macOS and Windows are ran in parallel. So in case of AppVeyor and Travis the resulting build time would be 30-32 minutes. With Azure DevOps this can be brought down to 13-14 minutes.

I would argue that merging two build scripts into one and cutting build time roughly in half are good arguments for why Azure DevOps seems to be a better fit for Fabulous. Then again there was some pain on getting the .Net CLI tools running, which I hope the Azure DevOps team will solve in the future - being products from the same company and all cough

Another aspect was having a build on Linux in the future, since Fabulous supports GTK since 0.30 it would be nice to also compile it on Linux. At the time of writing there were still a few kinks in the build process of Fabulous, but nothing that can't be solved in the future.


Thank you Timothé Larivière and Stuart Lang for all the tips and hints along the way


For my recent blog post about how to consume a web service in the Portable Class Library (PCL) I decided to write the client for Windows 10 which allows to create apps for every platform that runs Windows 10. In this post I will focus on the platforms Desktop, Tablet and Mobile showing how to create a basic application based on a MVVM architecture. To create a Windows 10 app you will need a computer running Windows 10 and Visual Studio 2015.

Creating a basic app

First lets create a list of people that we can navigate to in the detail view. Here fore we will create two pages. On the first page MainPage.xaml we will simply show the list:

    DataContext="{Binding Main, Source={StaticResource Locator}}"

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <GridView ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"></GridView>

        <AppBar VerticalAlignment="Bottom" IsOpen="True" >
            <AppBarButton Icon="Add" Label="Add Person" Command="{Binding AddNewPerson}" />

The user can select an element of the list on which we will navigate to the detail of the person allowing us to edit the person. This is done in the MainViewModel.cs which is based on the MVVM Light Framework for implementation:

public class MainViewModel:ViewModelBase
    private readonly IPersonService _personService;
    private ObservableCollection<Person> _people;
    private Person _selectedPerson;

    public MainViewModel(IPersonService personService)
        if (personService == null) throw new ArgumentNullException(nameof(personService));
        _personService = personService;
        _people = new ObservableCollection<Person>();
        ShowPerson = person => { };
        AddNewPerson = new RelayCommand(() => ShowPerson(-1));

    public ObservableCollection<Person> People => _people;
    public Action<int> ShowPerson { get; set; }

    public Person SelectedPerson
        get { return _selectedPerson; }
            if (_selectedPerson == value) return;
            _selectedPerson = value;
            if (_selectedPerson != null) ShowPerson(_people.IndexOf(_selectedPerson));

    public ICommand AddNewPerson { get; private set; }

    public async Task Init()
        var people = await _personService.GetPeople();


        foreach (var person in people)

The View Model also prepares the List of people that is displayed on the main page. The PersonDetailPage.xaml will allow to edit the first and surname of the person:

    DataContext="{Binding Person, Source={StaticResource Locator}}"

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBox Header="Firstname" Text="{Binding Firstname, Mode=TwoWay}"/>
        <TextBox Header="Lastname" Text="{Binding Lastname, Mode=TwoWay}"/>
        <Button Content="Save" Command="{Binding StoreCommand, Mode=TwoWay}" IsEnabled="{Binding HasPendingChanges}" HorizontalAlignment="Center" Margin="0,10"/>

When selecting save the person will be updated, all the logic is implemented in the PersonDetailViewModel.cs:

public class PersonDetailViewModel:ViewModelBase
    private readonly IPersonService _personService;
    private int _id;
    private string _firstname;
    private string _lastname;
    private bool _hasPendingChanges;

    public PersonDetailViewModel(IPersonService personService)
        if (personService == null) throw new ArgumentNullException(nameof(personService));
        _personService = personService;

        StoreCommand = new RelayCommand(StorePerson, () => true);
        HasPendingChanges = false;

    public bool HasPendingChanges
        get { return _hasPendingChanges; }
            if (value == _hasPendingChanges) return;
            _hasPendingChanges = value;

    public string Firstname
        get { return _firstname; }
            if (value == _firstname) return;
            _firstname = value;
            HasPendingChanges = true;

    public string Lastname
        get { return _lastname; }
            if (_lastname == value) return;
            _lastname = value;
            HasPendingChanges = true;

    public ICommand StoreCommand { get; set; }

    public async Task Init(int id)
        _id = id;
        var person = id > 0 ? (await _personService.GetPeople()).ToList()[id] : new Person("", "");
        Firstname = person.FirstName;
        Lastname = person.LastName;
        HasPendingChanges = false;

    private async void StorePerson()
        HasPendingChanges = false;

        var person = new Person(Firstname, Lastname);

        if (_id >= 0)
            await _personService.UpdatePerson(_id, person);
            await _personService.CreatePerson(person);

To prevent the user from invoking the storing of a person multiple times the store button is only enabled when there are pending changes and you probably want to improve the error handling in production code as it is non-existent in the StorePerson method.

Basic Navigation

From the main page we implement the navigation in MainPage.xaml.cs which allows the user to navigate to the detail page. We also pass along a navigation parameter which contains the ID or ahem in this basic example the array index of the person we want to see:

private void ShowPerson(int personId)
    Frame.Navigate(typeof (PersonDetailPage), personId);
    _viewModel.SelectedPerson = null;

The navigation is done over Frame.Navigate, which takes the type of the target and a parameter as an argument. The SelectedPerson is then set to null, after invoking the navigation. This is done so that the user may reselect the person the second time around.

Additionally when the user adds a person over the AppBar it will invoke the same navigation method but pass in the –1 as parameter indicating that no Index is set.

Further the user has the possibility to navigate back to the main page. Here fore we have to enable the back navigation which we set in the Loaded event handler of the person detail page and add an event handler for the BackRequest:

private void PersonDetail_OnLoaded(object sender, RoutedEventArgs e)
    SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
    SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;

The event handler is implemented as follows:

private void OnBackRequested(object sender, BackRequestedEventArgs backRequestedEventArgs)
    if (Frame.CanGoBack)
        backRequestedEventArgs.Handled = true;

While testing the app under Windows 10 mobile I noticed that the navigation was invoked twice when selecting the hardware back button. By setting the Handled property to true in the event arguments the framework is indicated that the navigation has been taken care of.

Taking it to other form factors

A great thing about creating your apps as a Universal Windows Platform app is that the APIs remain the same across the devices. In regards to the upcoming Windows 10 Mobile release we can even reuse the UI code. So we can run this basic app on a phone without making any changes. The UI will be automatically adopted to the new form factor.

Now of course for more complex apps you will want to use different layouts according to the screen size, but even then you will be creating adaptive layouts (same as with responsive Websites) rather than developing multiple apps to target different platforms. So a lot less overhead and work to have a running app across multiple form factors.


In this post we saw how to create a basic Windows 10 UWP app including basic navigation features and how to implement the MVVM pattern. If you are coming from a WPF, Silverlight, Windows 8.x or Windows Phone background you have seen that a lot of elements are very familiar.

I’ve been lately playing around with F# which unfortunately is currently not a supported language to write UWP apps. This also includes not being able to share Portable Class Libraries with UWP apps. If you feel the same way as me or want to throw the F# community a bone please let Microsoft know that they enable support for F# UWP apps here.

You can find the entire sample code of this blog post on GitHub.

  •   Posted in: 
  • F#


In this post I want to look at how to get started with Unit Testing while developing F#. I’m usually writing my code in C# and prefer to write my code in a TDD fashion, just to be on the safe side and sleep sound during the nights Winking smile In  my last blog post I looked at how to create a Web API service with F# and ended up testing the controller manually via a browser. So lets look how we can extend that solution to provide an automated way to test the controller.

Adding a test project

I’ll be using xUnit to create my tests. To get started you will just need a standard F# .Net Library (do not choose a Portable Class Library i.e. PCL). Then via NuGet add the following package:

PM> Install-Package xunit -Version 2.0.0

To be able to test the controller we must also add the FSharpWebSample project to the References. Now we can start writing tests as for example we can see in CarsControllerTest.fs:

namespace FSharpWebSample.Test
open Xunit
open FSharpWebSample.Controllers

module CarsControllerTest =

    let carsController = new CarsController()

    let Get_WhenInvoked_ReturnsAListContainingMultipleElements() = 
        let cars = carsController.Get()

    let GetWithIndex_WhenInvokedWithAValidIndex_ReturnsASingleItem() = 
        let car = carsController.Get(2)
        Assert.True(car.Id = 2)

Ensure that the xUnit and Controllers namespace is referenced in the test class:

open Xunit
open FSharpWebSample.Controllers

Running the tests

We can use the Test Explorer from Visual Studio run our tests as the xUnit runner NuGet package will make the xUnit tests visible to it. Simply add the package to the test project:

PM> Install-Package xunit.runner.visualstudio -Version 2.0.1
Then we can run the tests via Test, Runand finally All Tests. After executing our tests we get the all green.

Showing test runner after executing the tests.


In this post we saw how Unit Tests can be created for and executed to ensure our code is running correctly. Which reduces the load on manual testing and ensures that single code blocks work within expected parameters.

You can find the entire project on GitHub.


In this post I want to look at how to create a Web API project with F# and host it on Azure. This will part of a blog series on how to create a mobile application (incl. the backend) based on F#. The blog post assumes that you the reader has a basic understanding of how to create a Web API web service.

F# is a functional programming language based on the .Net Framework which contrary to many other functional programming languages also makes it a general purpose language. In my endeavor to explore a functional programming language I chose F# as it will allow me to create not only .Net applications but also Xamarin based cross platform apps.

To deploy to Azure you will need a valid Azure account. Alternatively you can run the App on your local machine.

Setting up the project

I’ll be using Visual Studio 2015 RC for this setup but you can follow along on VS 2013 just as well. Create a new project then go to Online projects, Select Visual F# and then select F# MVC 5. This only has to be done during the first setup. From now on you will find the project template under the Installedproject templates.


Having a look at the solution

If you are familiar with a Web API solution you will find yourself right at home.


Under Controllers you find the expected definitions, as well as under models. The Global.asax.fs also has a familiar ring to it:

namespace FSharpWebSample

open System
open System.Net.Http
open System.Web
open System.Web.Http
open System.Web.Routing

type HttpRoute = {
    controller : string
    id : RouteParameter }

type Global() =
    inherit System.Web.HttpApplication() 

    static member RegisterWebApi(config: HttpConfiguration) =
        // Configure routing
            "DefaultApi", // Route name
            "api/{controller}/{id}", // URL with parameters
            { controller = "{controller}"; id = RouteParameter.Optional } // Parameter defaults
        ) |> ignore

        // Configure serialization
        config.Formatters.XmlFormatter.UseXmlSerializer <- true
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver <- Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()

        // Additional Web API settings

    member x.Application_Start() =
        GlobalConfiguration.Configure(Action<_> Global.RegisterWebApi)

Extending the Controller

When we look at the controller we see that an array of the model is created and there is on method that will return the list. Let’s extend the controller to return a value requested by it’s Id. So first we have to extend the model Car.fs:

namespace FSharpWebSample.Models

open Newtonsoft.Json

type Car = {
    Make : string
    Model : string
    Id : int

Now we can extend the CarsController.fs so that we can filter the list and get the according value:

namespace FSharpWebSample.Controllers
open System
open System.Collections.Generic
open System.Linq
open System.Net.Http
open System.Web.Http
open FSharpWebSample.Models

/// Retrieves values.
type CarsController() =
    inherit ApiController()
    let values = [ { Make = "Ford"; Model = "Mustang"; Id = 1 }; { Make = "Nissan"; Model = "Titan"; Id = 2 }; { Make = "Audi"; Model = "R8"; Id = 3 } ]
    /// Gets all values.
    member x.Get() = values
    member x.Get(id:int) = values |> List.filter(fun v -> v.Id = id)

Deploying to Azure

Deploying to azure luckily is luckely the same as it always has been for C#, right click onto the Web API project, select Publish…, Microsoft Azure Web Apps then create a new web app enter a name and finally click on Pubish. Now all that is left is to test the web service so lets do this the manual way.

Testing the controller

Opening the prefered browser of your choice e.g. the new Edge browser enter the path to the azure website and be executing the following URI:


We receive the entire list:


When we add a Id parameter:


We only receive the requested record:



Creating a Web API service with F# is not much different than creating it with C# thanks to Ryan Riley and Daniel Mohl who provide the F# MVC 5 template. Also uploading it to Azure and sending requests are the way one would expect the service to run. Looking forward to go on further down the F# rabbit hole.

You can find the sample on GitHub.