forked from ServiceStack/ServiceStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExpressionUtils.cs
More file actions
139 lines (118 loc) · 4.95 KB
/
ExpressionUtils.cs
File metadata and controls
139 lines (118 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using ServiceStack.Logging;
namespace ServiceStack
{
public static class ExpressionUtils
{
private static readonly ILog Log = LogManager.GetLogger(typeof(ExpressionUtils));
public static PropertyInfo ToPropertyInfo(this Expression fieldExpr)
{
return ToPropertyInfo(fieldExpr as LambdaExpression)
?? ToPropertyInfo(fieldExpr as MemberExpression);
}
public static PropertyInfo ToPropertyInfo(LambdaExpression lambda)
{
return lambda?.Body.NodeType == ExpressionType.MemberAccess
? ToPropertyInfo(lambda.Body as MemberExpression)
: null;
}
public static PropertyInfo ToPropertyInfo(MemberExpression m)
{
var pi = m?.Member as PropertyInfo;
return pi;
}
public static string GetMemberName<T>(Expression<Func<T, object>> fieldExpr)
{
var m = GetMemberExpression(fieldExpr);
if (m != null)
return m.Member.Name;
throw new NotSupportedException("Expected Property Expression");
}
public static MemberExpression GetMemberExpression<T>(Expression<Func<T, object>> expr)
{
var member = expr.Body as MemberExpression;
var unary = expr.Body as UnaryExpression;
return member ?? unary?.Operand as MemberExpression;
}
public static Dictionary<string, object> AssignedValues<T>(this Expression<Func<T>> expr)
{
var initExpr = expr?.Body as MemberInitExpression;
if (initExpr == null)
return null;
var to = new Dictionary<string, object>();
foreach (MemberBinding binding in initExpr.Bindings)
{
to[binding.Member.Name] = binding.GetValue();
}
return to;
}
public static string[] GetFieldNames<T>(this Expression<Func<T, object>> expr)
{
var member = expr.Body as MemberExpression;
if (member != null)
{
if (member.Member.DeclaringType.AssignableFrom(typeof(T)))
return new[] { member.Member.Name };
var array = CachedExpressionCompiler.Evaluate(member);
var strEnum = array as IEnumerable<string>;
if (strEnum != null)
return strEnum.ToArray();
}
var newExpr = expr.Body as NewExpression;
if (newExpr != null)
return newExpr.Arguments.OfType<MemberExpression>().Select(x => x.Member.Name).ToArray();
var init = expr.Body as MemberInitExpression;
if (init != null)
return init.Bindings.Select(x => x.Member.Name).ToArray();
var newArray = expr.Body as NewArrayExpression;
if (newArray != null)
{
var constantExprs = newArray.Expressions.OfType<ConstantExpression>().ToList();
if (newArray.Expressions.Count == constantExprs.Count)
return constantExprs.Select(x => x.Value.ToString()).ToArray();
var array = CachedExpressionCompiler.Evaluate(newArray);
var strArray = array as string[];
if (strArray != null)
return strArray;
return array.ConvertTo<string[]>();
}
var unary = expr.Body as UnaryExpression;
if (unary != null)
{
member = unary.Operand as MemberExpression;
if (member != null)
return new[] { member.Member.Name };
}
throw new ArgumentException("Invalid Fields List Expression: " + expr);
}
public static object GetValue(this MemberBinding binding)
{
switch (binding.BindingType)
{
case MemberBindingType.Assignment:
var assign = (MemberAssignment)binding;
var constant = assign.Expression as ConstantExpression;
if (constant != null)
return constant.Value;
try
{
return CachedExpressionCompiler.Evaluate(assign.Expression);
}
catch (Exception ex)
{
Log.Error("Error compiling expression in MemberBinding.GetValue()", ex);
//Fallback to compile and execute
var member = Expression.Convert(assign.Expression, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
return getter();
}
}
return null;
}
}
}