添加 HttpClientFactory 导致 cancellationTokenSource 出错
Adding HttpClientFactory causing errors with cancellationTokenSource
我的 HttpClientFactory 有问题,我正在尝试将来自 DI 的 CancellationTokenSource 注入到我的 "SomeClient" 中,配置如下:
services.AddHttpClient<ISomeClient, SomeClient>(a =>
a.BaseAddress = new Uri(address))
并且我在 AddScoped<>() 的 Startup.cs 中注入 cancellationTokenSource。
如果我将 CancellationTokenSource 添加到 SomeClient 构造函数,它将显示
Cannot resolve scoped service 'System.Threading.CancellationTokenSource' from root provider.
但是如果我创建类似的东西:
services.AddScoped<ISomeClient, SomeClient>();
并在构造函数中新建一个本地HttpClient,并注入CancellationTokenSource,一切都会好起来的。
所以我的问题是如何将 CancellationTokenSource 与 HttpClientFactory 一起使用?
对于AddHttpClient
,它将SomeClient
注册为Transient
。但是你将 CancellationTokenSource
注册为 Scoped
。这是根源造成的。
HttpClientFactoryServiceCollectionExtensions.cs
public static IHttpClientBuilder AddHttpClient<TClient>(this IServiceCollection services)
where TClient : class
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
AddHttpClient(services);
var name = TypeNameHelper.GetTypeDisplayName(typeof(TClient), fullName: false);
var builder = new DefaultHttpClientBuilder(services, name);
builder.AddTypedClient<TClient>();
return builder;
}
HttpClientBuilderExtensions
public static IHttpClientBuilder AddTypedClient<TClient>(this IHttpClientBuilder builder)
where TClient : class
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Services.AddTransient<TClient>(s =>
{
var httpClientFactory = s.GetRequiredService<IHttpClientFactory>();
var httpClient = httpClientFactory.CreateClient(builder.Name);
var typedClientFactory = s.GetRequiredService<ITypedHttpClientFactory<TClient>>();
return typedClientFactory.CreateClient(httpClient);
});
return builder;
}
因此,您可以尝试将 CancellationTokenSource
注册为 Transient
。
services.AddTransient<CancellationTokenSource>();
我的 HttpClientFactory 有问题,我正在尝试将来自 DI 的 CancellationTokenSource 注入到我的 "SomeClient" 中,配置如下:
services.AddHttpClient<ISomeClient, SomeClient>(a =>
a.BaseAddress = new Uri(address))
并且我在 AddScoped<>() 的 Startup.cs 中注入 cancellationTokenSource。
如果我将 CancellationTokenSource 添加到 SomeClient 构造函数,它将显示
Cannot resolve scoped service 'System.Threading.CancellationTokenSource' from root provider.
但是如果我创建类似的东西:
services.AddScoped<ISomeClient, SomeClient>();
并在构造函数中新建一个本地HttpClient,并注入CancellationTokenSource,一切都会好起来的。
所以我的问题是如何将 CancellationTokenSource 与 HttpClientFactory 一起使用?
对于AddHttpClient
,它将SomeClient
注册为Transient
。但是你将 CancellationTokenSource
注册为 Scoped
。这是根源造成的。
HttpClientFactoryServiceCollectionExtensions.cs
public static IHttpClientBuilder AddHttpClient<TClient>(this IServiceCollection services)
where TClient : class
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
AddHttpClient(services);
var name = TypeNameHelper.GetTypeDisplayName(typeof(TClient), fullName: false);
var builder = new DefaultHttpClientBuilder(services, name);
builder.AddTypedClient<TClient>();
return builder;
}
HttpClientBuilderExtensions
public static IHttpClientBuilder AddTypedClient<TClient>(this IHttpClientBuilder builder)
where TClient : class
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Services.AddTransient<TClient>(s =>
{
var httpClientFactory = s.GetRequiredService<IHttpClientFactory>();
var httpClient = httpClientFactory.CreateClient(builder.Name);
var typedClientFactory = s.GetRequiredService<ITypedHttpClientFactory<TClient>>();
return typedClientFactory.CreateClient(httpClient);
});
return builder;
}
因此,您可以尝试将 CancellationTokenSource
注册为 Transient
。
services.AddTransient<CancellationTokenSource>();