lundi 15 juillet 2019

factorisation of similar function call

Context:

I consume a ERP WebService exposing N methods like:

FunctionNameResponse FunctionName(FunctionNameQuery query)

I made a functional wrapper in order to:

  • Get rid off wraper object FunctionNameResponse and FunctionNameQuery, that every method has.
  • One instance of the WebService for all the program.
  • Investigate and log error in the wrapper.
  • Investigate Slow running and Soap envelope with IClientMessageInspector


Code:

For each of the Methodes of the WebService I end up with around trithy lines of code with only 3 distincts words. Type response, type query, method name.

public FooResponse Foo(FooQuery query)
{
// CheckWebServiceState();
FooResponse result = null;
try
{
result =
WSClient
.Foo(query)
.response;
}
catch (Exception e)
{
// SimpleTrace();
// SoapEnvelopeInterceptorTrace();
// TimeWatch_PerformanceIEndpointBehaviorTrace();
}
return result; }

I would like to reduce those repetition. In order to :

  • Make it easier to add a Method;
  • Avoid copy pasting programming with no need to understand what you are doing.
  • Easier to add specific catch and new test without the need to copy past in every method.

The following code work and exist only in the imaginary realm. It's a not functional sketch of my solution using my limited understanding.

public class Demo
{
    public enum WS_Method
    {
        Foo,Bar,FooBar
    }
    public class temp
    {
        public Type Query { get; set; }
        public Type Response { get; set; }
        public WS_Method MethodName { get; set; }
    }
    public static IEnumerable<temp> TestFunctions =>
        new List<temp>
        {
            new temp{Query=typeof(FooQuery), Response=typeof(FooResponse), MethodName=WS_Method.Foo },
            new temp{Query=typeof(BarQuery), Response=typeof(BarResponse), MethodName=WS_Method.Bar },
            new temp{Query=typeof(FooBarQuery), Response=typeof(FooBarResponse), MethodName=WS_Method.FooBar },
        };
    public static void Run()
    {   // Exemple of consuming the method 
        var input = new BarQuery { Bar_Label = "user input", Bar_Ig = 42 };

        BarResponse result = Execute<BarQuery, BarResponse>(input);
    }
    public static T2 Execute<T1,T2>(T1 param) {
        //Get temp line where Query type match Param Type.
        var temp = TestFunctions.Single(x => x.Query == typeof(T1));
        var method = typeof(DemoWrapper).GetMethod(temp.MethodName.ToString(), new Type[] { typeof(T1) });
        var wsClient = new DemoWrapper();

        T2 result = default(T2);
        try
        {
            result =
                    method
                        .Invoke(wsClient, new object[] { param })
                        .response;
        }
        catch (Exception e)
        {
            // SimpleTrace();
            // SoapEnvelopeInterceptorTrace();               
            // TimeWatch_PerformanceIEndpointBehaviorTrace();
        }

        return result;
    }

}

I know the reflexion is heavy and perhaps it's not the right way to achieve this refactorisation. So the question is:

How do I refactorize those function?

attachment : Live demo https://dotnetfiddle.net/aUfqNp.





Aucun commentaire:

Enregistrer un commentaire