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;
}
}
}