quarta-feira, 23 de julho de 2014

Criando seu "bloco" de execução

Faz algum tempo que procuro um meio de executar códigos antes e depois da execução de um método, de forma limpa. Estava procurando isto especificamente por causa desde tipo de código:

    public void MyMethod()
    {
            BeginTransaction();

            try
            {

                    [meu código para executar no DB]

                    CommitTransaction();
            }
            catch (Exception)
            {
                    RollbackTransaction();
                    throw;
            }

    }

Este código é complexo de entender, e suja muito os métodos, principalmente se eu tiver que repeti-lo diversas vezes. Além disso, corre o risco, como já aconteceu, de eu esquecer de colocar alguma parte dele (por exemplo, o CommitTransaction).

Procurei um meio de colocar apenas um Attribute acima do método, e ele entender que quero cercar o método com o meu código. Descobri que é necessário mexer com um nível mais baixo, e até há uma biblioteca (paga) que posso baixar para fazer isso por mim.

Mas encontrei uma sugestão que, apesar de não ser tão limpa quanto colocar um Attribute, deixa o código simples e é como se você criasse um bloco de execução seu: http://stackoverflow.com/questions/6046382/suggestions-for-making-a-reusable-try-catch-block-in-c

Seguindo o exemplo, meu código acima ficaria assim:

    public void MyMethod()
    {
            InTransaction(() =>
            {
                    [meu código para executar no DB]
            });
    }

    protected void InTransaction(Action action)
    {
            BeginTransaction();
            try
            {

                    action();

                    CommitTransaction();
            }
            catch (Exception)
            {
                    RollbackTransaction();
                    throw;
            }

    }

Assim todos os métodos que forem usar transaction apenas precisarão ser colocados dentro desse bloco novo. Se for necessário retornar valor, a mudança nesse código seria esta:

    public T MyMethod()
    {
            return InTransaction(() =>
            {
                    return [meu código para executar no DB]
            });
    }

    protected T InTransaction<T>(Func<T> action)
    {
            BeginTransaction();
            try
            {

                    var result = action();

                    CommitTransaction();




                    return result;
            }
            catch (Exception)
            {
                    RollbackTransaction();
                    throw;
            }

    }

Assim é possível encurtar o código e diminuir os erros que podem ser cometidos ao programar.

Nenhum comentário:

Postar um comentário