我有一些API客户端可以发出请求。这些在启动中进行了描述。
简单地说,通过基类创建HttpClient并从基调用通用请求方法是否有意义。还是每个控制器都应该创建自己的客户端?有问题吗?
基础
public class BaseController : ControllerBase
{
public HttpClient client;
public BaseController(IHttpClientFactory factory, string clientName)
{
client = factory.CreateClient(clientName);
}
public async Task<IActionResult> Get(string query)
{
}
}
Foo
public class FooController : BaseController
{
public FooController(IHttpClientFactory factory) : base(factory, "fooclient")
{
}
[HttpGet]
public async Task<IActionResult> Get(int id)
{
return await Get($"Foo/Get/{id}");
}
}
答案 0 :(得分:1)
这种方法在技术上没有什么问题,但是最好使用类型化的客户端。完成的方法是通过创建将拥有客户端的“服务”类:
public class FooService
{
private readonly HttpClient _httpClient;
public FooService(HttpClient httpClient)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
}
...
}
然后,您在ConfigureServices
中注册它:
services.AddHttpClient<FooService>(c =>
{
// configure your HttpClient
});
最后,您将此服务类注入到控制器中:
public class FooController : ControllerBase
{
private readonly FooService _fooService;
public FooController(FooService fooService)
{
_fooService = fooService ?? throw new ArgumentNullException(nameof(fooService));
}
...
}
然后,这用于封装您的HttpClient
逻辑。您只需向服务添加方法即可执行控制器所需的操作,然后服务会发出实际的HttpClient
请求来执行此操作。如果您正在使用的API应该更改,那么这使更改事情变得无限容易。您只需更改服务就可以了,而不必跟踪使用HttpClient
与该API进行交互的每个位置,这是一项艰巨的任务。
此外,键入客户端可以使您一次配置一次,也可以在一处添加重试和异常处理策略等内容。由于为特定类型(例如FooService
)注入了客户端,因此对于客户端名称,没有任何魔术字符串可能会让您发胖或弄乱。