Drazar
Drazar

Reputation: 110

Help on refactor code duplication, using() try{} catch{}

I have taken over a project that uses WCF-services. The code have some ”code smells” and I want to Refactor these smells and I need advice on how to refactor a code duplication smell. Every method that is called by the WCF service looks like this:

public Result MyMethod(string aString, string bString)
{
    string methodName = MethodBase.GetCurrentMethod().Name;
    using (LogService log = LogFactory.Create())
    {
        try
        {
             <stmts>
             log.Info(methodName, "Created entity xyz");
             <stmts>
        }
        catch (Exception ex)
        { 
            log.Error(methodName, ex.message);
        }

    }
}

Question is how do I refactor this code? Every WCF call uses this "code template".

Upvotes: 0

Views: 658

Answers (4)

petro.sidlovskyy
petro.sidlovskyy

Reputation: 5103

It is crosscutting functionality like: logging, exception handling, etc. You may use AOP to eliminate it. Otherwise I would not recommend you to refactor this code. Here is good one AOP framework for .NET: http://www.sharpcrafters.com/ but it is not free :). You may want to search for free ones.

Upvotes: 0

vc 74
vc 74

Reputation: 38179

You can invoke the following with a before and an after action:

    private static void ActionWithLog(Action before, Action after)
    {
        string methodName = MethodBase.GetCurrentMethod().Name;
        using (LogService log = LogFactory.Create())
        {
            try
            {
                before();
                log.Info(methodName, "Created entity xyz");
                after();
            }
            catch (Exception ex)
            {
                log.Error(methodName, ex.message);
            }
        }
    }

for instance:

ActionWithLog(() => service.Operation1(), () => service.Operation2());

Upvotes: 4

codymanix
codymanix

Reputation: 29520

You can make this code a method and call it, passing the internal code as delegate or Action/lambda expression:

public Result MyMethod(string aString, string bString, MyDelegate a, MyDelegate b)
{
    string methodName = MethodBase.GetCurrentMethod().Name;
    using (LogService log = LogFactory.Create())
    {
        try
        {
             a();
             log.Info(methodName, "Created entity xyz");
             b();
        }
        catch (Exception ex)
        { 
            log.Error(methodName, ex.message);
        }

    }
}

then call it like:

MyMethod("foo", "bar", delegate{/*your code goes here*/}, delegate{/*your code goes here*/});

If you do not like inline delegates, create your delegates from separate methods like this:

MyMethod("foo", "bar", new MyDelegate(myMethodA), new MyDelegate(myMethodB));

Upvotes: 2

Danny Staple
Danny Staple

Reputation: 7332

The one nice thing about exceptions is that they bubble up if they aren't caught. So having them caught a level (or few) above, in one larger try catch and logging would help. The .stacktrace property of the exception will have the method name in it, and it would probably be very handy to log that instead of just the message and method name so you are not loosing that information.

Upvotes: 2

Related Questions