我正在编写.Net Core类库,它是REST Web服务的包装器。我正在使用HttpClient should be instantiated as a singleton。
我现在面临的一个大问题是如何管理这个HttpClient实例?它应该是我的类库的角色,还是将实例传递给我的类库的调用代码。
我从第一个解决方案开始,以这种方式创建单例实例:
public class DemoClient : IDemoClient
{
private static readonly HttpClient HttpClient;
static DemoClient()
{
HttpClient = new HttpClient();
}
public DemoClient(Uri baseUrl)
{
HttpClient.BaseAddress = baseUrl;
}
}
我使用静态构造函数来实例化单例实例,并在“标准”构造函数中设置baseUrl。
我不喜欢这种方法。首先,如果我的类库的用户创建了该类的第二个实例,将baseUrl
设置为其他内容,它将完全中断,首先是因为一旦进行了查询,设置BaseAddress
抛出一个例外,其次是因为即使你可以,每个实例也不可能有不同的BaseAddress
。
这意味着要么强制用户创建我的类的单例,这意味着他将无法为两个不同的REST端点创建两个实例,或者我忘记了使HttpClient
实例单例但是这可能最终会导致浪费套接字的风险。
第二个解决方案意味着我只是将HttpClient
的实例化留给我的库的用户,并要求他将它传递给我的构造函数。它肯定会简化管理(至少对我而言:))但感觉就像漏掉了实现细节。
我可能在将来更改并使用与HttpClient
不同的方法,这不会对我的库用户产生任何影响。此外,它要求库的用户实际知道如何使用HttpClient
(以及如何正确使用它),这也不会感觉“正确”。
还有其他我没想过的选择吗?让HttpClient
实例成为单例的问题非常烦人......