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}