Search This Blog

15 September 2010

Avoding hardcoded propertynames in C# .NET

Using strings that denote the name of fields and properties of objects in code are always a bad thing. The reasons are many, its hard to refactor code that contains hardcoded strings with properties names here and there in the code and its easy to make a typo and write some of the property wrong.

Wouldn't it be better if it was possible to avoid this and gather the property from the object directly instead and thereby avoid having to make the typo in the first place?

Luckily this is quite possible with a bit of functionallity added into the project. The below code picks out the name of the property or field of and object and returns the string name for this item. I got this idé from David Morgantini blogpost http://davidmorgantini.blogspot.com/2009/07/nhibernate-disjunction.html

public static string GetFieldName<TObject>(Expression<Func<TObject, Object> exp)
{
     return Regex.Match(exp.ToString(), @"\.(.*)")
               .Groups[1].Value.TrimEnd(new[] { ')' });
}

The code can be used as this

GetFieldName<Book>(b => b.Title)

This will give the string "Title" which can be presumed to be a property of an object named Book.

A more informativ place to use this code is when using NHibernates criteria API which can be cluttered by string constants.

public IList<Book> GetBooksByAuthor(string author)
{
    return Session.CreateCriteria(typeof(Book))
             .Add(Restrictions.Eq("Author", author)
             .List<Book>();
}

Can instead be written as

public IList<Book> GetBooksByAuthor(string author)
{
    return Session.CreateCriteria(typeof(Book))
             .Add(Restrictions.Eq(GetFieldName(b =>
                                              b.Author), author)
             .List<Book>();
}

Hopefully this can help you out with getting more managed code which is easier to maintain in a good state.






2 comments:

  1. This is available in NH 3.0, which will be available this fall.

    http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx

    ReplyDelete
  2. You can try also LINQ to NHibernate to do all that stuff.

    ReplyDelete