Netcore 2.1 servicecollection добавляет типизированные httpclients, которые не разрешаются должным образом

Я столкнулся с проблемой, когда Netcore 2.1 добавлял несколько типизированных HttpClient в ServiceCollection. Это работает не так, как ожидалось, и дает мне странные результаты.

Рассмотрим мой тест

var services = new ServiceCollection();

services.AddHttpClient<IHttpGenericClientFactory<test1>, HttpGenericClientFactory<test1>>(client =>
{
    client.BaseAddress = new Uri("https://test1.com/");
});

services.AddHttpClient<IHttpGenericClientFactory<test2>, HttpGenericClientFactory<test2>>(client =>
{
    client.BaseAddress = new Uri("https://test2.com/");
});

Теперь при попытке разрешить каждую службу

var provider = services.BuildServiceProvider();

var service1 = provider.GetService<IHttpGenericClientFactory<test1>>();
var service2 = provider.GetService<IHttpGenericClientFactory<test2>>();

Когда я проверяю service1.BaseAddress, значение равно «https://test2.com/», а service2.BaseAddress также равно «https://test2.com/». Независимо от того, что я пробовал, служба всегда разрешает или ссылается на последнюю добавленную универсальную типизированную службу. Это ошибка во фреймворке? Кто-нибудь знает, почему это не работает должным образом? Это определенно связано с типичными типизированными http-клиентами.

Мой общий класс и интерфейс

public interface IHttpGenericClientFactory<out T3>
{
    HttpClient HttpClient { get; set; }
    Task<T1> Get<T1, T2>(T2 request, string path);
}

public class HttpGenericClientFactory<T3> : IHttpGenericClientFactory<T3>
{
    public HttpClient HttpClient { get; set; }

    public HttpGenericClientFactory(HttpClient httpClient) => this.HttpClient = httpClient;

    public async Task<T1> Get<T1,T2>(T2 request, string path)
    {
        var response = await HttpClient.GetAsync(path);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsAsync<T1>();
    }
}
0
0
731
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете разрешить на основе различия в аргументе универсального типа аргумента универсального типа. Лучшее, что я могу порекомендовать, - это создать конкретные производные, на которые затем можно будет ссылаться явно:

public class Test1ClientFactory : HttpGenericClientFactory<Test1> {}

public class Test2ClientFactory : HttpGenericClientFactory<Test2> {}

Потом:

services.AddHttpClient<Test1ClientFactory>(client =>
{
    client.BaseAddress = new Uri("https://test1.com/");
});

services.AddHttpClient<Test2ClientFactory>(client =>
{
    client.BaseAddress = new Uri("https://test2.com/");
});

Только что попробовал этого приятеля, но результат тот же. Я думаю, что вы, возможно, правы, пытаясь решить проблему с помощью общих типов для служб httpclient.

James Dev 13.09.2018 22:02

Извините, я понял, что не прояснил, что вам также нужно будет вместо этого внедрить эти производные классы.

Chris Pratt 14.09.2018 08:25

Я пошел с абстрактным классом вместо того, чтобы пытаться сделать его универсальным интерфейсом, и он отлично работает таким образом

James Dev 15.09.2018 10:21

@JamesDev, можешь рассказать, как ты это делаешь?

Can Ürek 22.03.2020 00:10

Другие вопросы по теме