Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic AddHttpClient selected instead of non-generic #16422

Open
aklefdal opened this issue Dec 11, 2023 · 5 comments
Open

Generic AddHttpClient selected instead of non-generic #16422

aklefdal opened this issue Dec 11, 2023 · 5 comments
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Feature Improvement Needs-More information
Milestone

Comments

@aklefdal
Copy link

aklefdal commented Dec 11, 2023

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

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>.

@smoothdeveloper
Copy link
Contributor

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.

@aklefdal
Copy link
Author

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

@smoothdeveloper
Copy link
Contributor

@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.

@gusty
Copy link
Contributor

gusty commented Dec 16, 2023

Might be related to fsharp/fslang-suggestions#905

@0101
Copy link
Contributor

0101 commented Jan 29, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Feature Improvement Needs-More information
Projects
Status: New
Development

No branches or pull requests

4 participants