main
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Linq.Expressions;
 5using System.Reflection;
 6using gorilla.commons.utility;
 7
 8namespace MoMoney.Presentation.Winforms.Helpers
 9{
10    static public class EventTrigger
11    {
12        const BindingFlags binding_flags =
13            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance;
14
15        static readonly IDictionary<ExpressionType, Func<Expression, object>> expression_handlers;
16
17        static EventTrigger()
18        {
19            expression_handlers = new Dictionary<ExpressionType, Func<Expression, object>>();
20            expression_handlers[ExpressionType.New] = instantiate_value;
21            expression_handlers[ExpressionType.MemberAccess] = get_value_from_member_access;
22            expression_handlers[ExpressionType.Constant] = get_constant_value;
23        }
24
25        static public void trigger_event<Target>(Expression<Action<Target>> expression_representing_event_to_raise,
26                                                 object target) where Target : IEventTarget
27        {
28            var method_call_expression = expression_representing_event_to_raise.Body.downcast_to<MethodCallExpression>();
29            var method_args = get_parameters_from(method_call_expression.Arguments);
30            var method_name = method_call_expression.Method.Name;
31            var method = target.GetType().GetMethod(method_name, binding_flags);
32
33            method.Invoke(target, method_args.ToArray());
34        }
35
36        static object get_constant_value(Expression expression)
37        {
38            return expression.downcast_to<ConstantExpression>().Value;
39        }
40
41        static object get_value_from_member_access(Expression expression)
42        {
43            var member_expression = expression.downcast_to<MemberExpression>();
44            var type = member_expression.Member.DeclaringType;
45            var member = (FieldInfo) member_expression.Member;
46            var value = member.GetValue(Activator.CreateInstance(type));
47            return value;
48        }
49
50        static object instantiate_value(Expression expression)
51        {
52            var new_expression = expression.downcast_to<NewExpression>();
53            var args = new_expression.Arguments.Select(x => get_value_from_evaluating(x));
54            return new_expression.Constructor.Invoke(args.ToArray());
55        }
56
57        static IEnumerable<object> get_parameters_from(IEnumerable<Expression> parameter_expressions)
58        {
59            foreach (var expression in parameter_expressions)
60            {
61                if (can_handle(expression)) yield return get_value_from_evaluating(expression);
62                else cannot_handle(expression);
63            }
64        }
65
66        static void cannot_handle(Expression expression)
67        {
68            throw new ArgumentException("cannot parse {0}".formatted_using(expression));
69        }
70
71        static object get_value_from_evaluating(Expression expression)
72        {
73            return expression_handlers[expression.NodeType](expression);
74        }
75
76        static bool can_handle(Expression expression)
77        {
78            return expression_handlers.ContainsKey(expression.NodeType);
79        }
80    }
81}