I’m using Castle Active Record for a project that I’m on and I constantly find myself having to provide column names when creating queries through the ActiveRecordMediator<T> object. Here’s an example:
ActiveRecordMediator<Customer>.FindOne(Expression.Eq("FirstName", "Bob"));
The column name “FirstName” is not strongly typed. If I change that name (or anyone else does) and they don’t use a tool like ReSharper they might run into some issues.
So I poked around a bit and found a few examples of what I was trying to do and created my own strongly typed version with this class:
/// <summary>
/// Returns the name of a property via an expression.
/// </summary>
/// <typeparam name="TypeToParsePropertiesFrom">The type to parse properties from.</typeparam>
public interface IPropertyNameResolver<TypeToParsePropertiesFrom>
{
/// <summary>
/// Parses a property from the given type.
/// </summary>
/// <typeparam name="PropertyToParse">The property to parse.</typeparam>
/// <param name="property">The property.</param>
/// <returns>The property name.</returns>
string ResolvePropertyName<PropertyToParse>(Expression<Func<TypeToParsePropertiesFrom, PropertyToParse>> property);
}
/// <summary>
/// Class responsible for parsing a property name.
/// </summary>
/// <typeparam name="TypeToParsePropertiesFrom">The type to parse properties from.</typeparam>
public class PropertyNameResolver<TypeToParsePropertiesFrom> : IPropertyNameResolver<TypeToParsePropertiesFrom>
{
public string ResolvePropertyName<PropertyToParse>(Expression<Func<TypeToParsePropertiesFrom, PropertyToParse>> property)
{
//
// If the expression body was x.FirstName, it would return a string "x.FirstName".
//
var fullPropertyName = property.Body.ToString();
//
// Parse the index of the period and get the propertyName after that.
// therefore x.FirstName would return "FirstName"
//
return fullPropertyName.Substring(fullPropertyName.IndexOf(".") + 1);
}
}
Usage:
To get a property name using this expression you will need to use a Lambda. Check it out:
IPropertyNameResolver<Customer> customerResolver =
new PropertyNameResolver<Customer>();
var propertyName = customerResolver.ResolvePropertyName(x => x.FirstName);
Assert.That(propertyName, Is.EqualTo("FirstName"));
The only real con is that I have to create an instance of that generic class to do this. But … the good thing is that its strongly typed.


