• 0

Trying to Create a Method Signature I'm Happy With


Question

I'm trying to create a base interface / class that I am happy with that can accept a class type, request, and response. I can't quite get it structured the way I want it to be. I essentially want to have a helper assembly that will wrap any call on a given interface and perform things like timing, exception logging, etc. I want something similar to this:


var response = ServiceCaller.MakeServiceCall<Response, Request)>(SomeServiceClass.MyMethod(request));

return response;

 

I can't seem to quite get the code to be structured this way though. The closest I can get is:


public interface IWebServiceCaller<T>
        where T : class
    {
        R MakeServiceCall<R, C>(Expression<Func<T, Func<C, R>>> expression);
    }

 

public class WebServiceCaller<T>

 where T : class

{

         public R MakeServiceCall3<R, C>(Expression<Func<T, R>> expression, C request)
        {
            var exp = expression.Compile();
            ValidateRequest(request);
            var response = exp.Invoke(ServiceClass);

            return response;
        }

}

 

You have to pass the request object to be able to access it outside the expression it seems with this method though. I haven't used expressions that much I must admit. Is there something I'm missing here? I wish I could remove that extra C request parameter and still access the instance being passed in. If I change Expression<Func<T, R>> to Expression<Func<T, C, R>>, it gets even more awkward it seems.

 

Part of me is thinking I don't need the T, since my class doesn't really care about what type is being called. That could change method on the interface to just R MakeServiceCall3<R, C>, but then I still would need to pass the method to be called and an extra parameter for type C (like so: MakeServiceCall3<R, C>(serviceFuncDelegate, C request);

 

Maybe I'm trying to force this structure too much. I like the general idea of it, just can't get the code structured the way I would like.

1 answer to this question

Recommended Posts

  • 0

What's wrong with:

TReturn WrapRequest<TReturn>(Func<TReturn> f) {
     try {
         // start timing
         return f();
     }
    catch // etc.
    finally // log timing, etc.
}

Called as such:

 

WrapRequest(() => SomeServiceClass.MyRequest(request));

It's not clear to me what your requirements are, if this isn't satisfactory could you explain why?

 

If you need access to the request parameter then just pass it separately:

TReturn WrapRequest<TReturn, TParam>(Func<TParam, TReturn> f, TParam p) {
      // try-catch, time, log, do whatever you want with p, etc.
      return f(p);
}

WrapRequest(SomeServiceClass.MyRequest, request);

This is less flexible because the number of parameters is hardcoded; you'd need a separate overload for each different number of parameters.

This topic is now closed to further replies.