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.
Leave a Reply
You must be logged in to post a comment.