ASP NET Core 2.1 предоставил нам HttpClientFactory, который является отличным способом создания настраиваемых httpClients.
Мы использовали этот метод вместе со службой конфигурации конечной точки, которая была внедрена в конструктор класса startup.cs.
Код выглядел примерно так:
public Startup(IConfiguration configuration, IEndpointService endpointService)
{
Configuration = configuration;
_endpointService = endpointService;
}
public void ConfigureServices(IServiceCollection services)
{
foreach(var endpoint in _endpointService)
{
services.AddHttpClient(endpoint.name, c => {
c.BaseAddress = endpoint.Address;
// plus other config as required
});
}
}
IEndpointService был настроен до внедрения Startup с помощью следующего вызова.
IWebHostBuilder webHostBuilder =
WebHost.CreateDefaultBuilder(args)
.ConfigureServices((webHostBuilderContext, services) => {
services.AddSingleton<IEndpointService, EndpointService>();
})
.UseStartup<Startup>();
Это позволило нам считывать информацию из внешнего источника данных и настраивать несколько именованных httpClients с разной конфигурацией.
Эта функция была удалена в ASP NET Core 3.0.
См .: https://weblogs.thinktecture.com/pawel/2017/08/aspnet-core-beware-singleton-may-not-be-singleton.html и https://andrewlock.net/avoiding-startup-service-jection-in-asp-net-core-3/
Это оставляет нам вопрос, как лучше всего достичь той же функциональности в версии 3.0.
Это лучшее, что я придумал до сих пор, но я очень хочу знать, каковы рекомендации по этому вопросу.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IEndpointService, EndpointService>();
using (var serviceProvider = services.BuildServiceProvider())
{
var endpointService = serviceProvider.GetService<IEndpointService>();
foreach (var endpointConfiguration in endpointService.GetEndpointConfiguration())
{
// Create a named client and any other configuration that we need to do here.
services.AddHttpClient(endpointConfiguration.Name, client =>
{
client.BaseAddress = endpointConfiguration.BaseAddress;
// Add any extra config that is required here
});
}
}
}
В этом примере я принудительно создаю EndpointService с помощью serviceProvider.GetService.
Я осознаю тот факт, что я, вероятно, воссоздал ошибку с несколькими одиночками (см. Ссылки выше), но не уверен, что здесь лучший подход.
Мысли ?