Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / WPF

General DynamicObject Proxy and Fast Reflection Proxy

Rate me:
Please Sign up or sign in to vote.
5.00/5 (8 votes)
15 Sep 2010CPOL5 min read 42.1K   643   32  
Extending functionality by wrapping entity using DynamicObject. Improving performance of Reflection by using cache and expressions
using System;
using System.Linq.Expressions;
using System.Reflection;

namespace SysBits.Expressions
{
	//based on http://habrahabr.ru/blogs/net/103558/
	public static class PropertyInfoExtensions
	{
		public static Func<object, T> GetValueGetter<T>(this PropertyInfo propertyInfo)
		{
			if (!propertyInfo.CanRead || propertyInfo.GetGetMethod() == null) return null;
			var instance = Expression.Parameter(typeof(Object), "i");
			var castedInstance = Expression.ConvertChecked(instance, propertyInfo.DeclaringType);
			var property = Expression.Property(castedInstance, propertyInfo);
			var convert = Expression.Convert(property, typeof(T));
			var expression = Expression.Lambda(convert, instance);
			return (Func<object, T>)expression.Compile();
		}

		public static Action<object, T> GetValueSetter<T>(this PropertyInfo propertyInfo)
		{
			if (!propertyInfo.CanWrite || propertyInfo.GetSetMethod() == null) return null;
			var instance = Expression.Parameter(typeof(Object), "i");
			var castedInstance = Expression.ConvertChecked(instance, propertyInfo.DeclaringType);
			var argument = Expression.Parameter(typeof(T), "a");
			var setterCall = Expression.Call(
				castedInstance,
				propertyInfo.GetSetMethod(),
				Expression.Convert(argument, propertyInfo.PropertyType));
			return Expression.Lambda<Action<object, T>>(setterCall, instance, argument).Compile();
		}
	}

	//based on http://stackoverflow.com/questions/1272454/generate-dynamic-method-to-set-a-field-of-a-struct-instead-of-using-reflection
	public static class FieldInfoExtensions
	{
		public static Func<object, T> GetValueGetter<T>(this FieldInfo fieldInfo)
		{
			if (!fieldInfo.IsPublic) return null;
			var instance = Expression.Parameter(typeof(Object), "i");
			var castedInstance = Expression.ConvertChecked(instance, fieldInfo.DeclaringType);
			var field = Expression.Field(castedInstance, fieldInfo);
			var convert = Expression.Convert(field, typeof(T));
			var expression = Expression.Lambda(convert, instance);
			return (Func<object, T>)expression.Compile();
		}

		public static Action<object, T> GetValueSetter<T>(this FieldInfo fieldInfo)
		{
			if (!fieldInfo.IsPublic || fieldInfo.IsInitOnly) return null;
			var instance = Expression.Parameter(typeof(Object), "i");
			var castedInstance = Expression.ConvertChecked(instance, fieldInfo.DeclaringType);
			var argument = Expression.Parameter(typeof(T), "a");
			var setter = Expression.Assign(
				Expression.Field(castedInstance, fieldInfo),
				Expression.Convert(argument, fieldInfo.FieldType));
			return Expression.Lambda<Action<object, T>>(setter, instance, argument).Compile();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Israel Israel
Yury is Software Engineer since 1988.
His programming experience includes C#/VB.NET, WPF, C/C++(MFC/STL), Borland Delphi & C++ (VCL), JavaScript, HTML, CSS, XML, SQL, VB6, DirectX, Flash.
He has worked on PCs (DOS/Win3.1-Vista) and PocketPCs (WinCE).

Yury was born in Ukraine, but currently based in Jerusalem.

Comments and Discussions