3
\$\begingroup\$

Here is a code I want to simplify:

public void Method1(Context context, EventLog log = null)
{
    Class myClass = ConvertToMyClass();
    ApiCall1 apiCall = new ApiCall1(context);
    if (log != null)
    {
        eventLog.WriteEntry("Starting");
    }

    try
    {
        apiCall.Call1(myClass, null, false);
        IsCallSuccess = true;
    }
    catch (Exception e)
    {
        if (log != null)
        {
            eventLog.WriteEntry("error");
        }

        IsCallSuccess= false;
        CallErrorMessage = e.Message;
    }
}

public void Method2(Context context, EventLog log = null)
{
    Class myClass = ConvertToMyClass();
    ApiCall2 apiCall = new ApiCall2(context);
    if (log != null)
    {
        eventLog.WriteEntry("Starting");
    }

    try
    {
        apiCall.Call1(myClass);
        NewItemID = myClass.ItemID;
        IsCallSuccess = true;
    }
    catch (Exception e)
    {
        if (log != null)
        {
            eventLog.WriteEntry("error");
        }

        IsCallSuccess= false;
        CallErrorMessage = e.Message;
    }
}

public void Method3Context context, EventLog log = null)
{
    Class myClass = ConvertToMyClass();
    ApiCall3 apiCall = new ApiCall3(context);
    if (log != null)
    {
        eventLog.WriteEntry("Starting");
    }

    try
    {
        apiCall.Call3(myClass, "param1");
        UpdatedItemID = myClass.UpdatedItemID;
        IsCallSuccess = true;
    }
    catch (Exception e)
    {
        if (log != null)
        {
            eventLog.WriteEntry("error");
        }

        IsCallSuccess= false;
        CallErrorMessage = e.Message;
    }
}

There are 3 methods. I've been thinking about how I could simplify them using delegates or lambdas and didn't find anything.

Note that ApiCall1/2/3 are all defined in a third-party library. Your thoughts?

\$\endgroup\$
  • \$\begingroup\$ Do ApiCall1/2/3 all implement the same base class or interface? \$\endgroup\$ – Mike Perrenoud Oct 25 '12 at 11:42
  • \$\begingroup\$ Yes, they do... \$\endgroup\$ – Alan Coromano Oct 27 '12 at 16:03
4
\$\begingroup\$

Alright, let's see if we can simplifyabstract this for you. I'm not going to say simplify because often times abstracting something is far from simplifying it.

I think you can turn the method into something like this:

public void Method<T>(Context context, Action<T, Class> body, EventLog log = null)
{
    Class myClass = ConvertToMyClass();
    T apiCall = Activator.CreateInstance(typeof(T), new [] { context });
    if (log != null)
    {
        eventLog.WriteEntry("Starting");
    }

    try
    {
        body(apiCall, class);
        IsCallSuccess = true;
    }
    catch (Exception e)
    {
        if (log != null)
        {
            eventLog.WriteEntry("error");
        }

        IsCallSuccess = false;
        CallErrorMessage = e.Message;
    }
}

... then you should be able to call it like this:

// Method1
Method<ApiCall1>(
    yourContextInstance,
    (apiCall, myClass) =>
    {
        apiCall.Call1(myClass, null, false);
    },
    yourLogInstance);

// Method2
Method<ApiCall2>(
    yourContextInstance,
    (apiCall, myClass) =>
    {
        apiCall.Call1(myClass);
        NewItemID = myClass.ItemID;
    },
    yourLogInstance);

// Method3
Method<ApiCall3>(
    yourContextInstance,
    (apiCall, myClass) =>
    {
        apiCall.Call3(myClass, "param1");
        UpdatedItemID = myClass.UpdatedItemID;
    },
    yourLogInstance);

... one caveat is NewItemID and UpdatedItemID. If you're not making these calls from inside the class Method is defined in, you may need to modify this a tad to get the Method to return and integer instead.

\$\endgroup\$
  • \$\begingroup\$ Instead of Activator.CreateInstance(), you could use another delegate to make it more type-safe. \$\endgroup\$ – svick Oct 27 '12 at 11:58
  • \$\begingroup\$ I agree with svick. \$\endgroup\$ – Alan Coromano Oct 27 '12 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.