Как я могу избежать дублирования блоков try catch - PullRequest
11 голосов
/ 12 сентября 2011

У меня есть несколько методов, которые выглядят так:

public void foo()
{
   try 
   {
      doSomething();
   }
   catch(Exception e)
   {
      Log.Error(e);
   }
 }

Могу ли я изменить код, чтобы он выглядел как?

[LogException()]
public void foo()
{   
   doSomething();
}

Как я могу реализовать этот пользовательский атрибут?и каковы плюсы и минусы этого?

----- Редактировать 1 ------------

Могу ли я реализовать это сам, я имею в виду просто написать один класс, или мне нужно использоватьPostSharp или другое решение?

Ответы [ 4 ]

12 голосов
/ 12 сентября 2011

Вы можете использовать делегаты и лямбды:

private void ExecuteWithLogging(Action action) {
    try {
        action();
    } catch (Exception e) {
        Log.Error(e);
    }
}

public void fooSimple() {
    ExecuteWithLogging(doSomething);
}

public void fooParameter(int myParameter) {
    ExecuteWithLogging(() => doSomethingElse(myParameter));
}

public void fooComplex(int myParameter) {
    ExecuteWithLogging(() => {
        doSomething();
        doSomethingElse(myParameter);
    });
}

На самом деле, вы можете переименовать ExecuteWithLogging во что-то вроде ExecuteWebserviceMethod и добавить другие часто используемые вещи, такие как проверка учетных данных, открытие и закрытиеподключение к базе данных и т. д.

3 голосов
/ 12 сентября 2011

Поскольку вы упомянули, что используете WCF, вы можете реализовать интерфейс IErrorHandler, и все исключения будут перенаправлены в ваш метод, где вы сможете их регистрировать.

3 голосов
/ 12 сентября 2011

Вы можете попробовать использовать: PostSharp

или попробовать Google AOP - «Аспектно-ориентированное программирование».В Интернете есть больше подобных методов.

0 голосов
/ 12 сентября 2011

Если вы не хотите использовать подход AOP, метод, используемый у одного из моих предыдущих работодателей для общей обработки исключений в наборе классов, должен был иметь базовый класс с методом, подобным следующему

    protected TResult DoWrapped<TResult>(Func<TResult> action)
    {
        try
        {
            return action();
        }
        catch (Exception)
        {
            // Do something
            throw;
        }
    }

С методами, похожими на.

    public object AMethod(object param)
    {
        return DoWrapped(() =>
                      {
                          // Do stuff
                          object result = param;
                          return result;
                      });
    }

Не могу вспомнить точно, это было давно. Но похоже на это.

...