Я не могу воспроизвести проблему.
GetService
вернет ноль, если запрошенная служба не была зарегистрирована. Если был вызван GetRequiredService
, он бы выдал исключение.
В этом коде есть две проблемы.
Во-первых, эта строка:
services.AddTransient(y =>wrapper);
регистрирует фабричную функцию , которая возвращает тот же экземпляр HttpWrapper, а не сам экземпляр HttpWrapper. Эта функция вернет все, что содержит wrapper
.
Во-вторых, AddTransient
говорит, что это временный сервис, и все же один и тот же экземпляр будет возвращаться каждый раз.
Если одна и та же услуга используется каждый раз, при регистрации следует использовать AddSingleton
:
services.AddSingleton();
Если каждый раз требуется новый экземпляр , он должен быть :
services.AddTransient();
Тестовый код
Я использовал этот код для проверки проблемы и не могу воспроизвести ее:
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
try
{
HttpWrapper wrapper = new HttpWrapper();
services.AddTransient(provider => wrapper);
ServiceProvider prov = services.BuildServiceProvider();
HttpWrapper returned = prov.GetRequiredService();
Console.WriteLine("No problem");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Класс будет создан без каких-либо проблем. Единственный способ этого потерпеть неудачу - для wrapper
быть нулевым. Я использую GetRequiredService
, чтобы вызвать исключение, если регистрация не найдена.
Типизированные клиенты Http
Из комментариев выясняется, что проблема real заключается в том, как создать службу, которая правильно использует HttpClient. Повторное использование одного и того же экземпляра улучшит производительность, поскольку оно будет поддерживать существующие TCP-соединения в пуле соединений. Это все еще необходимо периодически перерабатывать, хотя для обработки изменения адресов DNS. Использование временного HttpClient плохо, но так же используется один экземпляр HttpClient.
HttpClientFactory решает обе проблемы, объединяя и перерабатывая экземпляров HttpClientHandler , которые фактически выполняют HTTP-запросы для каждого HttpClient. Статья Использование HttpClientFactory для реализации устойчивых HTTP-запросов объясняет, как это работает, но вкратце, просто добавив:
services.AddHttpClient();
Гарантирует, что каждый экземпляр CatalogService
будет обрабатываться должным образом HttpClient
. Все, что нужно CatalogService
, это принять HttpClient
в его конструкторе и использовать его в своих методах:
public class CatalogService : ICatalogService
{
private readonly HttpClient _httpClient;
public CatalogService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task GetCatalogItems(int page, int take,
int? brand, int? type)
{
....
var responseString = await _httpClient.GetStringAsync(uri);
...
}
}
Метод расширения AddHttpClient
доступен в Microsoft.Extensions.Http package
Адаптируя это к вопросу, HttpWrapper
должен принять параметр HttpClient в своем конструкторе:
public class HttpWrapper
{
private readonly HttpClient _cl;
public HttpWrapper(HttpClient client)
{
_cl=client;
}
public string TestUrl = "aaa";
}
и зарегистрироваться с AddHttpClient
:
[117 ]
После этого его можно решить с помощью:
var returned = prov.GetRequiredService();
Вы могли выполнить свой собственный сервер OpenID.
Вы не упоминали свою среду, но другая опция состоит в том, чтобы использовать аутентификацию Windows с Active Directory, если Вы работаете в ситуации с доменом Windows.
Вы хотите иметь единую точку входа между приложениями? (Таким образом, если тот же пользователь использует больше чем одно из Ваших веб-приложений, если они вошли в систему на одном, они не должны входить в систему снова, когда они перемещаются в другой.)
Если так, существует несколько опций, тем, который я использовал экстенсивно, является CAS (Сервис Централизованной аутентификации), который широко используется в учебных заведениях. Это имеет множество клиентских библиотек для многих языков, и часть сервера является Java.
Это может, конечно, быть объединено с LDAP для предоставления и единой точки входа и единого репозитория удостоверений пользователя.
Всегда существует некоторый LDAP, если Вы не в использование или свой собственный сервер OpenID или Windows Active Directory.