fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Generic AddHttpClient selected instead of non-generic

Open aklefdal opened this issue 2 years ago • 5 comments

I try to use Named HttpClient as described in the documentation from a Giraffe application.

    services.AddHttpClient(
        "poc",
        (fun httpClient -> httpClient.BaseAddress <- Uri("https://example.com")))
    |> ignore

Together with:

            let factory = ctx.GetService<IHttpClientFactory>()
            let httpClient = factory.CreateClient("poc")

This does not work since the F#-compiler chooses another overload to be used, the generic one.

Here is a small application that illustrates the problem: https://github.com/aklefdal/FSharpNamedHttpClient

  • How am I supposed register and use named HttpClients in F#?
  • Do I have to use classes and constructor injection of dependencies to make HttpClientFactory work?
  • Can I at least have warning issued from the compiler and possibly a way to force the compiler to use the right overload?

This issue is possibly related to

  • https://github.com/dotnet/fsharp/issues/12957
  • https://github.com/dotnet/fsharp/issues/11534

There is a workaround, and that is to add HttpClient as a generic argument to the call to AddHttpClient. This is not documented, nor do I know if it works in all cases. I don't even know why it works.

Update: There is a second workaround, and that is explicitly to cast the second argument to Action<HttpClient>.

aklefdal avatar Dec 11 '23 23:12 aklefdal

I believe you can do it with specifying the Action<HttpClient> explicitly:

services.AddHttpClient("should pick the one you want", Action<HttpClient>(fun httpClient -> httpClient.BaseAddress <- Uri("..."))) |> ignore

It would be interesting to make sure every overload can be called and to have non regression tests about the generated IL.

smoothdeveloper avatar Dec 12 '23 01:12 smoothdeveloper

Specifying the second parameter as Action<HttpClient> works as well. So this might just be the same issue as #11534

aklefdal avatar Dec 12 '23 07:12 aklefdal

@aklefdal it would be interesting to remove the "func is better" thing in the compiler and see how it behaves, and thanks to your issues being tracked, we can, in time, start putting test cases together around overload resolution and keep this in consideration to improve overload resolution.

smoothdeveloper avatar Dec 15 '23 05:12 smoothdeveloper

Might be related to https://github.com/fsharp/fslang-suggestions/issues/905

gusty avatar Dec 16 '23 18:12 gusty

We need to investigate and find out what's happening here exactly and then document the behavior or look if it can be solved as part of an existing suggestion.

We might not be able to fix it without breaking something else related to method resolution.

0101 avatar Jan 29 '24 17:01 0101