I, like many others, hate string literals. Of course, I mean string literals that have some meaning to the code itself, not the "hello, world" kind of strings. They are not type-safe, not easy to refactor, etc. The drawbacks have been mentioned a lot.
In particular, it always bothered me that NHibernate suffers from this problem, specially in the Criteria API. Well, now with C# 3 AST manipulation we can easily fix this. I wrote a simple set of helper classes and extension methods that provide an Expression parameter wherever there was a string parameter describing a property name. Let's see an example:
Instead of writing this:
IList cats = sess.CreateCriteria(typeof(Cat)) .Add( Expression.Like("Name", "F%") .AddOrder( Order.Asc("Name") ) .AddOrder( Order.Desc("Age") ) .SetMaxResults(50) .List();
You can write this:
IList cats = sess.CreateCriteria(typeof(Cat)) .Add( ExpressionEx.Like((Cat c) => c.Name, "F%") .AddOrder( OrderEx.Asc((Cat c) => c.Name) ) .AddOrder( OrderEx.Desc((Cat c) => c.Age) ) .SetMaxResults(50) .List();
which is a bit longer, but refactorable.
Code is here (NHibernate 1.2)
UPDATE 2/21/2009: Dan Miser has kindly submitted a patch to port these extensions to NHibernate 2.0.1GA. Code is here. Thanks Dan!
UPDATE 3/28/2010: Two years have passed now since I originally published this and several similar solutions have popped up. In particular, I recommend NH Lambda extensions for NHibernate 2.x which seems to be more complete, less verbose, and better maintained than my own solution. NHibernate 3 will have a new official API similar to this, named QueryOver. If you're stuck with NHibernate 1.2 the only solution available is the one presented in this article.
Related projects: