A Day In The Lyf

The lyf so short, the craft so longe to lerne

C# Execute Around Method

Posted by Brandon Byars Tue, 12 Jun 2007 04:46:00 GMT

Kent Beck called one of the patterns in Smalltalk Best Practice Patterns “Execute Around Method.” It’s a useful pattern for removing duplication in code that requires boilerplate code to be run both before and after the code you really want to write. It’s a much lighter weight method than template methods (no subclassing), which can accomplish the same goal.

As an example, I’ve written the following boilerplate ADO.NET code countless times:

public DataTable GetTable(string query, IDictionary parameters)

{

    using (SqlConnection connection = new SqlConnection(this.connectionString))

    {

        using (SqlCommand command = new SqlCommand(query, connection))

        {

            connection.Open();

            foreach (DictionaryEntry parameter in parameters)

            {

                command.Parameters.AddWithValue(parameter.Key.ToString(), parameter.Value);

            }

 

            SqlDataAdapter adapter = new SqlDataAdapter(command);

            using (DataSet dataset = new DataSet())

            {

                adapter.Fill(dataset);

                return dataset.Tables0;

            }

        }

    }

}

 

public void Exec(string query, IDictionary parameters)

{

    using (SqlConnection connection = new SqlConnection(this.connectionString))

    {

        using (SqlCommand command = new SqlCommand(query, connection))

        {

            connection.Open();

            foreach (DictionaryEntry parameter in parameters)

            {

                command.Parameters.AddWithValue(parameter.Key.ToString(), parameter.Value);

            }

 

            command.ExecuteNonQuery();

        }

    }

}

Notice that the connection and parameter management overwhelms the actual code that each method is trying to get to. And the duplication means I have multiple places to change when I decide to do something differently. However, since the using block encloses the relevant code, a simple Extract Method refactoring is not as easy to see.

Here’s the result of applying an Execute Around Method pattern to it.

private delegate object SqlCommandDelegate(SqlCommand command);

 

public DataTable GetTable(string query, IDictionary parameters)

{

    return (DataTable)ExecSql(query, parameters, delegate(SqlCommand command)

    {

        SqlDataAdapter adapter = new SqlDataAdapter(command);

        using (DataSet dataset = new DataSet())

        {

            adapter.Fill(dataset);

            return dataset.Tables0;

        }

    });

}

 

public void Exec(string query, IDictionary parameters)

{

    ExecSql(query, parameters, delegate(SqlCommand command)

    {

        return command.ExecuteNonQuery();

    });

}

 

private object ExecSql(string query, IDictionary parameters, SqlCommandDelegate action)

{

    using (SqlConnection connection = new SqlConnection(this.onnectionString))

    {

        using (SqlCommand command = new SqlCommand(query, connection))

        {

            connection.Open();

            foreach (DictionaryEntry parameter in parameters)

            {

                command.Parameters.AddWithValue(parameter.Key.ToString(), parameter.Value);

            }

 

            return action(command);

        }

    }

}

Much nicer, no?

Posted in | no comments | Tags , , | atom

Comments

Leave a response

Leave a comment