我有许多 WebService 方法,它们都包含一些非常样板的代码,将实际工作包装在 try/catch/finally 中,并在 catch/finally 中执行相同的任务。因此,作为封装所有共享 catch/finally 内容的方法,我编写了一个简单的泛型。
这确实有效,并且确实消除了一堆重复的代码,但感觉很笨拙,而且语法非常迟钝。每次我回到这个问题时,我的大脑都会扭曲,试图弄清楚它(一个明显的迹象表明这不是一个好的设计)。我正在寻找反馈,看看这是否是一件疯狂的事情,以及是否有更好的方法来解决它。
这是我的模板:
public delegate T2 RestfulServiceRequest<T1, T2>(T1 req);
static class RestfulService
{
public static T2 ExceptionHandler<T1, T2>(RestfulServiceRequest<T1, T2> serviceCall, T1 req)
{
if (req == null)
throw new BadRequestException(new ArgumentNullException("Invalid or missing request object"));
try
{
return serviceCall(req);
}
catch (RestfulException e)
{
// log it and rethrow
Logger.Write(e);
throw;
}
catch (Exception e)
{
Logger.Error(e);
// wrap in a consistent exception for propagation back to caller
throw new InternalServerException(e);
}
finally
{
Logger.Debug("Complete");
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
这是它的用法:
public class Initialization : IInitialization
{
// MyMethod thas uses the template
public ApplianceInitResp CreateApplianceServer(ApplianceInitReq req)
{
return RestfulService.ExceptionHandler<ApplianceInitReq, ApplianceInitResp>(delegate(ApplianceInitReq x)
{
// do some work
return new ApplianceInitResp();
}, req);
}
}
Run Code Online (Sandbox Code Playgroud)
}
我会改变
public static T2 ExceptionHandler<T1, T2>(RestfulServiceRequest<T1, T2> serviceCall, T1 req)
Run Code Online (Sandbox Code Playgroud)
到
public static T2 Invoke<T1, T2>( this T1 req, RestfulServiceRequest<T1, T2> serviceCall)
Run Code Online (Sandbox Code Playgroud)
这会将调用更改为
public class Initialization :IInitialization {
public ApplianceInitResp CreateApplianceServer( ApplianceInitReq req ) {
return req.Invoke( r => {
// do some work
return new ApplianceInitResp();
});
}
}
Run Code Online (Sandbox Code Playgroud)