Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Like Magic, No Strings Attached

0.00/5 (No votes)
28 Mar 2013 1  
Helper utility replaces magic string property names.

Well OK, one string attached, a dependency on LINQ.Expressions.

You may be familiar with using Lambda expressions in HtmlHelper extensions as a way to get away from magic strings. For instance, for a display template, you could use Html.Display("Message") which relies on the magic string "Message", or instead you could use Html.DisplayFor(m => m.Message) and the magic string disappears.

Or maybe you used ExpressionHelper.GetExpressionText to replace magic string property names from a Model in a View. ExpressionHelper.GetExpressionText has an overload that takes a Lambda expression and returns a string representing the property name. For example, ExpressionHelper.GetExpressionText(p => p.Name) would return the string "Name". I've found ExpressionHelper.GetExpressionText useful when testing the UI layer and I need to find a control by its name to check its value.

Leverage Visual Studio

With this technique of using helpers utilizing Lambda expressions to replace magic strings, you can leverage Visual Studio’s IntelliSense and Debugger to ensure you get property names right, before runtime, before your bugs bite.

The ExpressionHelper is part of Web.MVC but only gets property names from the Model and the HtmlHelper also only works in views. There are probably other parts of your application where you could use the same kind of functionality as these helpers and where you would like to leverage the Visual Studio IDE. It would be great to have a helper to be able to resolve any property name for any class to a string safely, accurately, and anywhere in your application it is needed and to have Visual Studio help you use it.

There are other variations to a helper like this but I found this one in Scott Millett’s "Professional ASP.NET Design Patterns". He calls it PropertyNameHelper and included it in his querying infrastructure namespace. The helper requires the LINQ.Expressions library. Other classes in his querying namespace make use of LINQ so it made good sense for him to have it there. But I found it useful in other areas of my projects. One use is when I create business rules for validation routines. My business rule objects are lists that I populate with string pairs of a property's name and its rule. I want to make sure to get the property name right, rather than making a typo, so I use the PropertyNameHelper.

My version of PropertyNameHelper is in a namespace called Helpers where I keep other general purpose utilities and is a static class with a static method I’ve named StringNameFor.

Using It Is Easy

Include a reference and a using to the Helpers namespace in your project and any classes your project references can be used by the helper. For a class named Product with a property named Price, you would use PropertyNameHelper.StringNameFor<Product>(p => p.Price)" to return the string "Price". It's that easy.

IntelliSense makes sure that both Product is a valid class and that Price is a valid property. Using PropertyNameHelper means you will always get "Price". You won’t get "Pirce" by mistake. And if you change the property name from Price to Cost, you can use refactoring tools to update all the references making your code a little less brittle and buggy. And using these helpers in your tests makes them less brittle too.

using System.Linq.Expressions; 

namespace Helpers
{
   public class PropertyNameHelper
   {
          public static string StringNameFor<T>(Expression<Func<T, object >> expression) 
          {
               var expr = expression.Body as MemberExpression; 
               if (expr == null) {
                    var u = expression.Body as UnaryExpression; 
                    expr = u.Operand as MemberExpression; 
               }
               return expr.ToString().Substring(expr.ToString().IndexOf(".") + 1); 
          }
     } 
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here