1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Linq.Expressions;
5: using System.Reflection;
6:
7: namespace Alon.Samples
8: {
9: /// <summary>
10: /// Init object with default values
11: /// </summary>
12: /// <typeparam name="T">The object that will be init</typeparam>
13: public static class Initializer<T> where T : new()
14: {
15: private static Action<T> _initFunction;
16:
17: static Initializer()
18: {
19: //The method that extract the value accurding to the attribute key
20: MethodInfo method = typeof(Initializer<T>).GetMethod("GetValue", BindingFlags.Static | BindingFlags.NonPublic);
21: var param = Expression.Parameter(typeof(T), "TObject");
22: //The expressions that we want to run
23: List<Expression> exps = new List<Expression>();
24: //Get all the properties that has DefaultValue attribute
25: var props = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(true).Where(a => a is DefaultValue).Any());
26: foreach (PropertyInfo propertyInfo in props)
27: {
28: MemberExpression prop = Expression.Property(param, propertyInfo);
29: DefaultValue defaultAttribute = propertyInfo.GetCustomAttributes(typeof(DefaultValue), true)[0] as DefaultValue;
30: ConstantExpression ce = Expression.Constant(defaultAttribute.Value);
31: MethodCallExpression call = Expression.Call(method, ce);
32: BinaryExpression assign = Expression.Assign(prop, call);
33: exps.Add(assign);
34: }
35: //If we dont have any attributes we will create an empty block (otherwise we will get an exception)
36: BlockExpression blockExpression = exps.Count > 0 ? Expression.Block(exps) : Expression.Block(Expression.Empty());
37: Expression<Action<T>> lamExp = Expression.Lambda<Action<T>>(blockExpression, param);
38: //Compile the method :)
39: _initFunction = lamExp.Compile();
40: }
41:
42: private static string GetValue(string key)
43: {
44: return key;
45: }
46:
47: public static void Init(T obj)
48: {
49: _initFunction(obj);
50: }
51: }
52: }