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

Keyed services aren't working with HttpClientBuilder #89446

Closed
xakep139 opened this issue Jul 25, 2023 · 6 comments
Closed

Keyed services aren't working with HttpClientBuilder #89446

xakep139 opened this issue Jul 25, 2023 · 6 comments

Comments

@xakep139
Copy link
Contributor

Description

It seems that IHttpClientFactory doesn't support newly added #64427.

Reproduction Steps

var services = new ServiceCollection();
var httpClientBuilder = services
    .AddHttpClient("named");

httpClientBuilder.Services.TryAddKeyedSingleton<MyClientLogger>(httpClientBuilder.Name);
httpClientBuilder.AddLogger(sp => sp.GetRequiredKeyedService<HttpClientLogger>(httpClientBuilder.Name));

using var provider = services.BuildServiceProvider();

var httpClientFactory = provider.GetRequiredService<IHttpClientFactory>();
using var httpClient = httpClientFactory.CreateClient("named");

And MyLogger simply implements IHttpClientLogger.

Expected behavior

No exception is thrown.

Actual behavior

System.InvalidOperationException is thrown with the next message: This service provider doesn't support keyed services.

Stack Trace:

    ServiceProviderKeyedServiceExtensions.GetRequiredKeyedService(IServiceProvider provider, Type serviceType, Object serviceKey)
    ServiceProviderKeyedServiceExtensions.GetRequiredKeyedService[T](IServiceProvider provider, Object serviceKey)
    <>c__DisplayClass25_0.<Test_test>b__0(IServiceProvider sp) line 773
    <>c__DisplayClass27_0.<AddLogger>b__1(HttpMessageHandlerBuilder b)
    <>c__DisplayClass17_0.<CreateHandlerEntry>g__Configure|0(HttpMessageHandlerBuilder b)
    <>c__DisplayClass3_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
    DefaultHttpClientFactory.CreateHandlerEntry(String name)
    <.ctor>b__1()
    Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
    Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
    Lazy`1.CreateValue()
    DefaultHttpClientFactory.CreateHandler(String name)
    DefaultHttpClientFactory.CreateClient(String name)
    MyTests.Test() line 778
    RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
    MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

Regression?

No response

Known Workarounds

No response

Configuration

.NET SDK 8.0.100-preview.7.23360.1
I was referencing runtime packages with version 8.0.0-rc.1.23373.2.

Other information

I haven't tried, but the same issue could probably be the case when ConfigureHttpClientDefaults() is used and in its configure action a keyed service is registered/resolved.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jul 25, 2023
@ghost
Copy link

ghost commented Jul 25, 2023

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

It seems that IHttpClientFactory doesn't support newly added #64427.

Reproduction Steps

var services = new ServiceCollection();
var httpClientBuilder = services
    .AddHttpClient("named");

httpClientBuilder.Services.TryAddKeyedSingleton<MyClientLogger>(httpClientBuilder.Name);
httpClientBuilder.AddLogger(sp => sp.GetRequiredKeyedService<HttpClientLogger>(httpClientBuilder.Name));

using var provider = services.BuildServiceProvider();

var httpClientFactory = provider.GetRequiredService<IHttpClientFactory>();
using var httpClient = httpClientFactory.CreateClient("named");

And MyLogger simply implements IHttpClientLogger.

Expected behavior

No exception is thrown.

Actual behavior

System.InvalidOperationException is thrown with the next message: This service provider doesn't support keyed services.

Stack Trace:

    ServiceProviderKeyedServiceExtensions.GetRequiredKeyedService(IServiceProvider provider, Type serviceType, Object serviceKey)
    ServiceProviderKeyedServiceExtensions.GetRequiredKeyedService[T](IServiceProvider provider, Object serviceKey)
    <>c__DisplayClass25_0.<Test_test>b__0(IServiceProvider sp) line 773
    <>c__DisplayClass27_0.<AddLogger>b__1(HttpMessageHandlerBuilder b)
    <>c__DisplayClass17_0.<CreateHandlerEntry>g__Configure|0(HttpMessageHandlerBuilder b)
    <>c__DisplayClass3_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
    DefaultHttpClientFactory.CreateHandlerEntry(String name)
    <.ctor>b__1()
    Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
    Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
    Lazy`1.CreateValue()
    DefaultHttpClientFactory.CreateHandler(String name)
    DefaultHttpClientFactory.CreateClient(String name)
    MyTests.Test() line 778
    RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
    MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

Regression?

No response

Known Workarounds

No response

Configuration

.NET SDK 8.0.100-preview.7.23360.1
I was referencing runtime packages with version 8.0.0-rc.1.23373.2.

Other information

I haven't tried, but the same issue could probably be the case when ConfigureHttpClientDefaults() is used and in its configure action a keyed service is registered/resolved.

Author: xakep139
Assignees: -
Labels:

area-Extensions-HttpClientFactory

Milestone: -

@xakep139
Copy link
Contributor Author

cc @CarnaViire @klauco

@xakep139 xakep139 changed the title Using keyed services in HttpClientBuilder Keyed services aren't working with HttpClientBuilder Jul 25, 2023
@CarnaViire
Copy link
Member

CarnaViire commented Jul 25, 2023

There are two issues here.

  1. The reason for the repro attached here -- Scoped ServiceProvider, acquired from a DI scope created by IServiceScopeFactory, does not implement the IKeyedServiceProvider (see ServiceProviderEngineScope.cs) -- I will create a separate issue for that in Microsoft.Extensions.DependencyInjection space (UPD: Injected or scoped ServiceProvider does not support Keyed services #89447)
  2. ConfigueHttpClientDefaults utilize a proxy service collection, which possibly should also support the interface -- this is an issue in Microsoft.Extensions.Http space, I will keep the current issue for tracking that.

UPD: there's no issue with ConfigueHttpClientDefaults, see comment below

@CarnaViire
Copy link
Member

So, thinking this through, there's actually no second issue. ConfigueHttpClientDefaults utilize a proxy service collection, not a service provider. There's no problem with that, the interface should only be implemented by a service provider.

I've checked that keyed services work just fine with a custom service collection.

@CarnaViire
Copy link
Member

@xakep139 I'm considering closing this as a duplicate of #89447, as there's nothing needs to be changed in HttpClientFactory.

Sadly there's no workaround I see, even suppressing scopes wouldn't help 😢 #89447 (comment)

@CarnaViire
Copy link
Member

Duplicate of #89447

@CarnaViire CarnaViire marked this as a duplicate of #89447 Jul 26, 2023
@CarnaViire CarnaViire closed this as not planned Won't fix, can't repro, duplicate, stale Jul 26, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jul 26, 2023
@karelz karelz added this to the 8.0.0 milestone Aug 1, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Aug 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants