Добавление HttpClientFactory, вызывающее ошибки с cancellationTokenSource - PullRequest
0 голосов
/ 05 декабря 2018

У меня проблема с HttpClientFactory, я пытаюсь внедрить CancellationTokenSource из DI в мой «SomeClient», который настроен так:

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

, и я ввожу cancellationTokenSource в Startup.csв AddScoped <> ().

Если я добавлю CancellationTokenSource в конструктор SomeClient, он скажет:

Невозможно разрешить выделенную службу 'System.Threading.CancellationTokenSource' от корневого поставщика.

но если я создам что-то вроде:

services.AddScoped<ISomeClient, SomeClient>();

и создаю новый локальный HttpClient в конструкторе и вставляю CancellationTokenSource, все будет хорошо.

Так что мойВопрос в том, как использовать CancellationTokenSource с HttpClientFactory?

1 Ответ

0 голосов
/ 06 декабря 2018

Для 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>();
...