Делегаты с различным количеством параметров - PullRequest
1 голос
/ 03 марта 2020

Я написал DLL, которая вызывает сторонний API, к которому у меня нет доступа.

Из-за того, как пользователь мог выйти и перезапустить приложение, каждый метод имеет много логики c вокруг проверки токенов Access и Refre sh для аутентификации с помощью API. (А также обработка ошибок) Это привело к большому количеству дублированного кода для каждого отдельного вызова API.

Я хочу реорганизовать это, чтобы я мог просто передать тип объекта ответа, который я хочу, универсальному c метод с именем ExecuteApiCall. Который затем может вызвать соответствующий метод только для указанного вызова REST c.

Я создал этот метод со следующей подписью:

private T ExecuteApiCall<T>(string name, Action<T> requestCall) where T : IApiResponse, new()

, и это работает так, как я и ожидал. У меня сейчас проблема в том, что для некоторых запросов требуются дополнительные параметры, и я не могу передать различное количество параметров делегату Action.

Как мне go справиться с этим?

Я думал о том, чтобы перейти на

Action<T, ApiRequestParameters>

, где ApiRequestParameters - это класс всех возможных параметров, а передний метод publi c может установить то, что ему нужно, перед вызовом частного ExecuteApiCall. Но на самом деле это не похоже на лучшую практику.

Я действительно надеюсь, что это имеет смысл для кого-то и заранее спасибо. Буду рад предоставить дополнительные примеры кода, если потребуется.

Следующее необходимо обработать

ExecuteCallA()
{
    //The API call is done here using RestSharp
}

ExecuteCallB(string aParameter)
{
    //The API call is done here using RestSharp
}

ExecuteCallC(string aParameters, int anotherParameter)
{
    //The API call is done here using RestSharp
}

Или было бы проще просто настроить действие так, чтобы оно выглядело примерно так.

Action<T, object, object, object>

Так что он может обрабатывать дополнительные параметры и просто игнорировать все, что ему не нужно.

РЕДАКТИРОВАТЬ:

Спасибо Шон за предложение, это вероятно, что я буду go с. Мой другой вариант, опять-таки не уверен в лучших практиках здесь ...

Было бы иметь подпись publi c, содержащую параметры метода, и установить их в закрытое поле.

private string myParameter;
public ApiResponseA GetWhatever(string a)
{
    myParameter = a;
    ExecuteApiCall<ApiResponseA>();
    myParameter = null;
}

Затем измените закрытый метод, отвечающий за фактический вызов API, на использование закрытого поля вместо параметра. Мысли?

1 Ответ

2 голосов
/ 03 марта 2020

Я бы добавил перегрузки для определенного количества параметров. Например:

private T ExecuteApiCall<T>(string name, Action<T> requestCall) where T : IApiResponse, new();

private T ExecuteApiCall<P1, T>(string name, P1 p1, Action<P1, T> requestCall) where T : IApiResponse, new()

private T ExecuteApiCall<P1, P2, T>(string name, P1 p1, P2 p2, Action<P1, P2, T> requestCall) where T : IApiResponse, new()

// etc

Это немного повторяется в реализации, но как только вы это сделаете, вы можете об этом забыть, и это сделает API, который вы предоставляете пользователям, намного чище и предсказуемее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...