У меня есть пользовательская HttpClient реализация, для работы которой требуются некоторые значения из моей конфигурации.
public class MyHttpClient : HttpClient
{
public MyHttpClient()
{
}
public MyHttpClient(string token)
{
Token = token;
}
public string Token { get; set; }
// ...
}
Теперь я хочу использовать этот HttpClient в моей логике приложения, которая использует IOptions<TOptions>
для получения его конфигурации.
public class MyLogic
{
private static MyHttpClient Client;
public MyLogic(IOptions<MyConfig> config)
{
// How to instantiate Client with values from config?
}
}
Поскольку HttpClient должен храниться как статическое поле , я борюсь с методом, которым я могу ввести значение конфигурации в HttpClient.Я предложил несколько возможностей, но ни одна из них, похоже, не подходит.
Опция 1 : устанавливать значение конфигурации каждый раз
public class MyLogic
{
private static MyHttpClient Client = new MyHttpClient();
public MyLogic(IOptions<MyConfig> config)
{
Client.Token = config.Value.Token;
}
}
Кажется, это наихудший вариант, поскольку значение Token
может измениться, поскольку HttpClient использует его.
Опция 2 : блокировка каждый раз
public class MyLogic
{
private static MyHttpClient Client;
private static readonly object ClientLock = new object();
public MyLogic(IOptions<MyConfig> config)
{
lock(ClientLock)
{
if (Client == null)
{
Client = new MyHttpClient(config.Value.Token);
}
}
}
}
Это кажется плохим с точки зрения производительности, поскольку каждое создание MyLogic
создаст блокировку и заблокирует все остальные.
Опция 3 : двойная проверка блокировки
public class MyLogic
{
private static volatile MyHttpClient Client;
private static readonly object ClientLock = new object();
public MyLogic(IOptions<MyConfig> config)
{
if (Client == null)
{
lock(ClientLock)
{
if (Client == null)
{
Client = new MyHttpClient(config.Value.Token);
}
}
}
}
}
Это похоже на решение, однакодвойные проверки блокировок трудно сделать правильно, и поэтому их следует избегать.
К сожалению, Lazy не представляется возможным, поскольку для этого также требуется статический контекст, напримерсоздание.
Итак, что будет лучшим вариантом для создания экземпляра HttpClient в этой ситуации?