We have a wcf web services API, which has some common code which we have wrapped into a generic method to save from having to write the same code in every web service method. This looks like so:
TResult SafeMethodCall<T, TResult>(Func<T, TResult, TResult> body, T request)
where TResult : ServiceResponse, new()
where T : RequestBase
{
if (request == null)
throw new ArgumentNullException("request");
var response = new TResult();
try
{
response = body(request, response);
}
catch (Exception ex)
{
AddServiceError(response, ex);
}
finally
{
AddAuditData(request, response);
}
return response;
}
Now I am trying to write the auditing functionality, and there is a particular parameter that is almost always part of the request or the response classes, so I can get this parameter using reflection so I can log it to the database.
private void AddAuditData(RequestBase request, ServiceResponse response)
{
string signinId = "";
Type t = request.GetType();
PropertyInfo info = t.GetProperty("SignInIdentifier");
if (info != null)
{
signinId = info.GetValue(request).ToString();
}
Type r = response.GetType();
info = r.GetProperty("SignInIdentifier");
if (info != null)
{
signinId = info.GetValue(response).ToString();
}
//now log signinid, and method name, etc to the database
//how do I pass signinid into this method if it isn't part of the request or response???
}
Each web service method has it's own version of the response and request classes which inherit from the base ones referenced in this method.
My problem is that for the one or two web service methods where I do not have access to the parameter I want to log, but instead I need to do some work to get it, I'm not sure how to pass it into the generic method to deal with it.
I could do this by using global variables or by adding it to the response classes, but either of those approaches seem quite shoddy from a programming style point of view.
I was wondering if anyone had any other suggestions for a "nice" way of handling this?