.NET C# Extension Methods - Reflection

Sunday, November 22, 2009

.NET C# Extension Methods - Reflection

Other extension methods:

---------------------------
I was wondering how to get the name of a property via reflection. So I searched the Internet and I found this on Google code. The code was not good enough though. I was not able to get a string name from level 3 (i.e: User.Name.First). I did a small modifications and ended with this class that works perfect.
    public static class MembersOf
    {
        public static string GetPath(System.Linq.Expressions.Expression> expr)
        {
            var node = expr.Body as System.Linq.Expressions.MemberExpression;
            if (ReferenceEquals(null, node))
                throw new System.InvalidOperationException("Expression must be of member access");

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            string result = BuildName(node, sb).Remove(0, 1).ToString();
            sb.Clear();

            return result;
        }

        static System.Text.StringBuilder BuildName(System.Linq.Expressions.MemberExpression expr, System.Text.StringBuilder sb)
        {
            if (ReferenceEquals(null, expr) == false)
            {
                sb.Insert(0, expr.Member.Name);
                sb.Insert(0, ".");

                BuildName(expr.Expression as System.Linq.Expressions.MemberExpression, sb);
            }

            return sb;
        }
    }
Now the question is where this code can be handy? I use this when I want to build NHibernate Criteria or DetachedCriteria. When you create a Criteria you use a code like this one:
ICriteria crit = session.CreateCriteria(typeof(Customer));
crit.Add(Expression.Eq("Customer.Name.First", someValue));
Here the Name property is a NHibernate component. The problem is that if you change the property Name to FirstName you will not get a compile error but you will get runtime error when the query is executed against the database. Also you can use some refactoring tool like RefactorPro! and the changes in the component will be applied also in the criteria. Nice, ahh?!? And the code above will be:
ICriteria crit = session.CreateCriteria(typeof(Customer));
crit.Add(Expression.Eq(MembersOf<Customer>.GetPath(x=>x.Name.First), someValue));


No comments:

Post a Comment