我有许多名为DataAdapter
的类,它们位于不同的文件夹中,每个类都包含用于访问外部API的唯一配置的HttpClient。我使用反射创建了正确版本的DataAdapter
类。
剪切下面的示例:
internal class DataAdapter : IDataAdapter
{
public HttpClient Client => GetClient();
static HttpClient GetClient()
{
// This implementation is unique to the API
var client = new HttpClient();
client.AcceptHeader(MediaType.Json);
client.AuthorizationHeader("123456");
client.Timeout = TimeSpan.FromSeconds(300);
return client;
}
}
此处的前提是每个API创建一个HttpClient
。因此,当第二个用户出现并实例化新的DataAdapter
类(在同一文件夹中)时,他们应该重用相同的HttpClient
。
如果用户在其他文件夹中实例化new DataAdapter
类,则应创建HttpClient
的其他版本(如果尚不存在)。
我不确定的是方法中的new HttpClient
-是该示例每次实例化此确切类的新实例时都会返回new HttpClient
还是仅创建一个?
答案 0 :(得分:0)
每次访问属性时,原始代码都会创建一个新的HttpClient
。使用以下代码将在第一次需要时创建一个,然后在此之后返回相同的代码:
internal class DataAdapter : IDataAdapter
{
public HttpClient Client => staticClient.Value;
static Lazy<HttpClient> staticClient = new Lazy<HttpClient>(()=>
{
// This implementation is unique to the API
var client = new HttpClient();
client.AcceptHeader(MediaType.Json);
client.AuthorizationHeader("123456");
client.Timeout = TimeSpan.FromSeconds(300);
return client;
});
}
这个想法是Lazy<T>
属性为您提供了一些好处。它会延迟HttpClient
的实例化,直到需要它为止。并且,它使线程安全而没有大惊小怪。使用 static Lazy<T>
意味着每个HttpClient
类都有一个单例DataAdapter
,它是及时初始化的;听起来就是您要尝试的。
基本上,当您要求client.Value
时,Lazy<T>
将在第一次使用提供的委托创建HttpClient
,并在第二次记住该值,同时确保线程安全为你。