A Day In The Lyf

…the lyf so short, the craft so longe to lerne

C# Execute Around Method

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?

About these ads

Written by Brandon Byars

June 11, 2007 at 11:46 pm

Posted in .NET, Design Patterns

Tagged with

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: