添加HttpClientFactory导致CancellationTokenSource错误

时间:2018-12-05 13:03:35

标签: c# dependency-injection .net-core asp.net-core-2.0 httpclientfactory

我在HttpClientFactory上遇到问题,我正在尝试将DI中的CancellationTokenSource注入配置为类似于我的“ SomeClient”中:

services.AddHttpClient<ISomeClient, SomeClient>(a =>
                a.BaseAddress = new Uri(address))

并且我正在将Startup.cs中的cancelTokenSource注入AddScoped <>()。

如果我将CancellationTokenSource添加到SomeClient构造函数,它将说

  

无法从根提供程序解析作用域服务'System.Threading.CancellationTokenSource'。

但是如果我创建类似这样的内容:

services.AddScoped<ISomeClient, SomeClient>();

并在构造函数中创建一个新的本地HttpClient,并注入CancellationTokenSource,一切都会好起来的。

所以我的问题是如何将CancellationTokenSource与HttpClientFactory一起使用?

1 个答案:

答案 0 :(得分:1)

对于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>();