Skip to content
A .NET Core 2.2 console app that uses Generic Host, but does not use an IHostedService. This time, in F#!
F#
Branch: master
Clone or download
jonsagara Linked to the C# version in the readme.
Updated to FSharp.Core 4.7.0.
Latest commit 9c7a3aa Aug 19, 2019

README.md

Use HttpClient via IHttpClientFactory in a .NET Core 2.2 console app without implementing IHostedService

If you're looking for the C# version, go here.

Not that there's anything wrong with IHostedService, but sometimes you just want a plain old console app without having to implement another interface just so that you can inject and use IHttpClientFactory.

There is still some ceremony involved with setting up the Generic Host HostBuilder so that you can inject IHttpClientFactory into your classes, but beyond that you merely create an IServiceScope to make everything work:

use serviceScope = host.Services.CreateScope()
let services = serviceScope.ServiceProvider

try
    let testSvc = services.GetRequiredService<TestService>()
    let html = testSvc.AsyncGetMicrosoft() |> Async.RunSynchronously
    printfn "%s" (String(html.Take(1_000).ToArray()))
with
    | ex -> 
        let logger = services.GetRequiredService<ILogger<Program>>()
        Console.Error.WriteLine(sprintf "Unhandled exception %s" (ex.ToString()))
        logger.LogError(ex, "Unhandled exception");

This code creates an IServiceScope in main, and then uses that to get our registered TestService class, which returns the HTML of https://www.microsoft.com as a string. We then display the first 1,000 characters.

The TestService class looks like this:

module TestService

    open System.Net.Http

    type TestService (httpClientFactory : IHttpClientFactory) =

        let _httpClient = httpClientFactory.CreateClient()

        member this.AsyncGetMicrosoft() =
            async {
                use requestMsg = new HttpRequestMessage(HttpMethod.Get, "https://www.microsoft.com")
                use! responseMsg = _httpClient.SendAsync(requestMsg) |> Async.AwaitTask
                let! content = responseMsg.Content.ReadAsStringAsync() |> Async.AwaitTask
                return content
            }

And now you can use all of the newfangled IHttpClientFactory goodness in a (mostly) plain old console app!

You can’t perform that action at this time.