HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Executing a stored procedure with optional attributes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
storedexecutingwithprocedureattributesoptional

Problem

Lately, I have been reading Uncle Bob's Clean Code book, and decided to try and follow some of his principles to make a class that was a somewhat confusing static helper class, with an abundance of private static methods, into an instance class which more clearly expresses its intent.

The problem is to execute a stored procedure based upon a variety of attributes that may be applied to it, like with with parameters, with a command timeout, or within a transaction, etc.

Class Code:

I have tried to emulate a builder pattern with a fluid API, so the class allows you to prepare the various attributes of before calling Execute to with those attributes.

```
public class StoredProcedureExecuter : IDisposable
where TResultSetType : class, new()
{
#region Fields

private readonly DbConnection _connection;
private readonly string _procedureName;
private readonly Type _resultSetType;
private bool _connectionAlreadyOpen;
private IEnumerable _procedureParameters;
private int? _commandTimeoutOverride;
private CommandBehavior _commandBehavior;
private SqlTransaction _transaction;
private DbCommand _command;

#endregion

#region Constructors

///
/// Initializes a new instance of the class.
///
/// The databse connection to execute the procedure against.
/// Name of the procedure to execute.
///
/// connection
/// or
/// procedureName
///
public StoredProcedureExecuter(
DbConnection connection,
string procedureName)
{
if (connection == null) throw new ArgumentNullException("connection");
if (string.IsNullOrWhiteSpace(procedureName)) throw new ArgumentNullException("procedureName");

_connection = connection;
_procedureName = procedureName;
_resultSetType = typeof(TResultSetType);
}

#endregion

#region Dispose and Finalise

///
/// Gets a value indicating whether this
/// is disposed.

Solution

-
The DbConnection class implements the IDbConnection interface, so unless you need something exposed by the Component base class, you could use the interface instead of the concrete type. This will make your code more flexible and testable.

-
If you're using C#6, you can use the nameof operator to refactor proof your argument exceptions.

... throw new ArgumentNullException(nameof(connection));


-
I don't see a benefit to storing the Type from the type parameter in an instance variable. You could get it only if you need it. A case of DRY gone too far? Maybe you know something I don't though.

It's really very pleasant to read this code, even if there's quite a bit of it. I'm also a big fan of fluent API's and it seems that you've implemented one that I wouldn't mind working with.

Code Snippets

... throw new ArgumentNullException(nameof(connection));

Context

StackExchange Code Review Q#113351, answer score: 5

Revisions (0)

No revisions yet.