NetInverse Developers Blog

February 8, 2010
Category: .Net — Tags: , — admin @ 10:32 pm

Dynamic reflection is the classic .Net reflection. Now there is a new pattern called “Static Reflection” which is very popular in some open source code like nHibernate. Static Reflection’s main
benefit is “refactoring” friendly. For example, in the following code snippet, if you use the static relfection and change the property name, it won’t break. If you use the string to locate the property, it will break easily.

    //Classic Reflection
    var entity = new SampleEntity();
    entity.SetValue(entity, "Id", 100); //dynamic binding
    entity.SetValue(entity, "Name", "Sample");

    //Static Relection
    var entity1 = new SampleEntity();
    entity1.SetValue(e => e.Id, 100); //early binding
    entity1.SetValue(e => e.Name, "Sample");
// Static reflections.cs

using System;
using System.Linq.Expressions;
using System.Reflection;

namespace LinqExpressionSample
{
    public class SampleEntity
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public void SetValue<T>(T entity, string propertyName, object value)
        {
            PropertyInfo propertyInfo = typeof (T).GetProperty(propertyName);
            propertyInfo.SetValue(entity, value, null);
        }

    }

    public static class Extension
    {
        public static void SetValue<T>(this T entity, Expression<Func<T, object>> expression, object value)
        {
            MemberExpression memberExpression = GetMemberExpression(expression);
            var propertyInfo = memberExpression.Member as PropertyInfo;
            propertyInfo.SetValue(entity, value, null);
        }

        private static MemberExpression GetMemberExpression<T, TValue>(Expression<Func<T, TValue>> expression)
        {
            if (expression == null)
            {
                return null;
            }
            if (expression.Body is MemberExpression)
            {
                return (MemberExpression)expression.Body;
            }
            if (expression.Body is UnaryExpression)
            {
                var operand = ((UnaryExpression)expression.Body).Operand;
                if (operand is MemberExpression)
                {
                    return (MemberExpression)operand;
                }
                if (operand is MethodCallExpression)
                {
                    return ((MethodCallExpression)operand).Object as MemberExpression;
                }
            }
            return null;
        }
    }
}

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

©2009 NetInverse. All rights reserved. Powered by WordPress