自定义 API 客户组织

Custom API Client organization

我有一个自定义 API 客户端调用具有许多控制器的自定义 API 服务。我实际上有这个 class:

public abstract class APIClientBase
{
    protected HttpClient _httpClient;

    public APIClientBase()
    {
        _httpClient = new HttpClient();
        _httpClient.BaseAddress = new Uri("https://localhost:44369/");
    }
}

许多 classes 都实现了这个:

public class APIClientEmployee : APIClientBase
{
    public async Task<ObservableCollection<Employee>> GetAllEmployeesRequestAsync()
    {
        ObservableCollection<Employee> employees = null;
        HttpResponseMessage response = await _httpClient.GetAsync($"api/employees");

        if (response.IsSuccessStatusCode)
        {
            employees = response.Content.ReadAsAsync<ObservableCollection<Employee>>().Result;
        }

        return employees;
    }

    public ObservableCollection<Employee> GetAllVeterinaryEmployeesRequest()
    {
        ObservableCollection<Employee> employees = null;
        HttpResponseMessage response = _httpClient.GetAsync($"api/employees/veterinaryemployees").Result;

        if (response.IsSuccessStatusCode)
        {
            employees = response.Content.ReadAsAsync<ObservableCollection<Employee>>().Result;
        }

        return employees;
    }

    public async Task<Employee> GetSingleEmployeeRequestAsync(int id)
    {
        Employee employee = null;
        HttpResponseMessage response = await _httpClient.GetAsync($"api/employees/{id}");

        if (response.IsSuccessStatusCode)
        {
            employee = response.Content.ReadAsAsync<Employee>().Result;
        }

        return employee;
    }

    public Employee GetSingleEmployeeRequest(int id)
    {
        Employee employee = null;
        HttpResponseMessage response = _httpClient.GetAsync($"api/employees/{id}").Result;

        if (response.IsSuccessStatusCode)
        {
            employee = response.Content.ReadAsAsync<Employee>().Result;
        }

        return employee;
    }

    public async Task PutSingleEmployeeRequestAsync(Employee employee)
    {
        HttpResponseMessage response = await _httpClient.PutAsJsonAsync($"api/employees/{employee.EmployeeID}", employee);
        response.EnsureSuccessStatusCode();
    }

    public async Task PostSingleEmployeeRequestAsync(Employee employee)
    {
        HttpResponseMessage response = await _httpClient.PostAsJsonAsync($"api/employees", employee);
        response.EnsureSuccessStatusCode();
    }

    public async Task DeleteSingleEmployeeRequestAsync(int id)
    {
        HttpResponseMessage response = await _httpClient.DeleteAsync($"api/employees/{id}");
        response.EnsureSuccessStatusCode();
    }
}

我在我的 ViewModels 中这样使用它们:

 public class EmployeeListViewModel
 {
    private APIClientEmployee _apiClientEmployee;

    private ObservableCollection<Employee> _employees;

    public ObservableCollection<Employee> Employees
    {
        get
        {
            return _employees;
        }
        set
        {
            _employees = value;
            OnPropertyChanged("Employees");
        }
    }

    public EmployeeListViewModel()
    {
        _apiClientEmployee = new APIClientEmployee();
        FillEmployeeList();
    }

    public async void FillEmployeeList()
    {
        Employees = await _apiClientEmployee.GetAllEmployeesRequestAsync();
    }
}

我在很多地方都做过这样的事情。此外,我在其他 ViewModel 中创建了其他 APIClientEmployee,因为我需要在其他一些地方使用 Employee 数据。但是这种方法让我创建了许多 APIClient objects/Http 客户端,我觉得我这样做的方式有问题。我想我可以打破我的套接字限制矿石这样的东西然后它会导致问题。我已经阅读了很多教程,但它们通常并不复杂。我应该只有一个 class 每个 API 调用吗?我应该用我的每个 APIClient classes 的一个实例实现一个单例吗?我不知道该怎么办,我想有建议...

你说的很对。查看 HttpClient:

上的官方文档

HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors. Below is an example using HttpClient correctly.

这是声明的方式

static readonly HttpClient client = new HttpClient();

您可以执行以下操作:

public abstract class APIClientBase
{
    protected static readonly HttpClient client = new HttpClient();

然后像这样使用:

HttpResponseMessage response = await APIClientBase.client.GetAsync($"api/employees/{id}");