A while back, Scott Hanselman started a series of posts about leveraging lambdas as anonymous functions for a factory pattern in his BabySmash program. Recently I had to refactor a large portion of the persistence layer and realized that I needed a factory that would create SqlParameters with the correct SqlDbType given different sets of circumstances. First the example factory code:
1: private Dictionary<Type, Func<string, object, SqlParameter>> _parameterDictionary =
2: new Dictionary<Type, Func<string, object, SqlParameter>>
5: typeof (short), (name, value) =>
7: SqlParameter p = new SqlParameter(name, value);
8: p.SqlDbType = SqlDbType.TinyInt;
13: typeof (int), (name, value) =>
15: SqlParameter p = new SqlParameter(name, value);
16: p.SqlDbType = SqlDbType.Int;
21: typeof (long), (name, value) =>
23: SqlParameter p = new SqlParameter(name, value);
24: p.SqlDbType = SqlDbType.BigInt;
Obviously, in the actual production version there's a lot more to it, but that should give enough of an example. So let me attempt to explain what's going on incase that's not intuitive. The dictionary is a key-value pair where the key is the .Net type for which the factory is creating the parameter and the value is a delegate with the method signature (string, object) and returns a SqlParameter instance. The reason for all the crazy brackets is that I'm actually using lambdas as anonymous functions to provide the implementation for the delegate defined as Func<string, object, SqlParameter>. This means that, at runtime, I can use the dictionary in the following way:
string parameterName = "@howMuchIsTooMuch";
string parameterValue = "eleventy billion";
SqlParameter parameter = _parameterDictionary[parameterValue.GetType()].Invoke(parameterName, parameterValue);
Why a dictionary? Well, it's actually more performant to allow the type to act as a key than to write switch or complex if/else routines which is part of what Hanselman was avoiding in his post. I hope this implementation of Hanselman's approach leads to other fun refactoring.