使用泛型封装通用方法工作

Bre*_*obi 5 c# generics

我有许多 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)

}

jyo*_*ung 2

我会改变

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)