Оболочка для функций с похожими, но не идентичными сигнатурами
Я использую API третьего уровня, который имеет ряд различных, но похожих объектов, связанных с HTTP, таких как:
TypeAService, TypeARequest, TypeAResponse
TypeBService, TypeBRequest, TypeBResponse
и т.п.
Шаблон для вызова всегда одинаков, что-то вроде:
myTypeXResponse = myTypeXService.SubmitRequest(myTypeXRequest);
Мне нужно обернуть эту строку в некоторый базовый код, который обрабатывает конкретные TypeXServiceException
отступая и повторяя некоторые другие детали, около 10 - 20 строк кода, которые я должен набирать снова и снова. Я ищу какой-то элегантный способ обернуть эту строку кода в функцию, которую я мог бы вызвать, указав метод, который должен быть вызван и ожидаемый тип исключения, что-то вроде:
myTypeXResponse = myWrapperFunction(myTypeXService.SubmitRequest, myTypeXRequest, typeof(TypeXServiceException));
Я попытался использовать функцию take и return для Objects, но чтобы передать функцию, мне нужно быть точным в сигнатуре функции, которую я не могу здесь сделать. Я чувствую, что есть какой-то способ сделать это с Generics, но мои исследования онлайн не дали мне ничего, что полностью ответило на мой вопрос.
Любая помощь с благодарностью.
2 ответа
Вы можете использовать дженерики для обработки этого:
public static T myWrapperFunction<T>(Func<T, T> func, T request)
//where T : //some common base type, if it helps
{
return func(request);
}
Метод, предложенный Servy для этой проблемы (с изменениями в моем последнем комментарии), в течение некоторого времени работал очень хорошо, но недавно я решил аналогичную проблему с другим подходом, используя делегаты вместо шаблонов. Я опубликую это здесь на тот случай, если кто-то может воспользоваться кодом:
public delegate bool TryAgainAfterException(Exception ex);
public void RepeatAction(Action action, TryAgainAfterException tryAgainFunction)
{
// set up whatever logic you would use for your do-while loop here
bool tryAgain;
do
{
tryAgain = false;
try
{
action();
}
catch (Exception ex)
{
if (tryAgainFunction(ex))
{
// the specific logic of the Exception
// handling would go here, including:
tryAgain = true;
}
else
throw ex;
}
}
while (tryAgain);
}
Теперь я могу получить свой объект ответа, заключив вызов в Action:
RepeatAction( () => { myTypeXResponse = myTypeXService.SubmitRequest(myTypeXRequest); },
e => e.GetType() == TypeXServiceException );
На самом деле я не защищаю один метод перед другим, но я тоже хотел поделиться этим.