-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTypeMap.cs
More file actions
140 lines (107 loc) · 5.12 KB
/
TypeMap.cs
File metadata and controls
140 lines (107 loc) · 5.12 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
140
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;
using DataAvail.Utils;
namespace DataAvail.LinqMapper
{
internal static class TypeMap
{
internal static Type GetGenericEnumerableType(Type Enumerable)
{
if (Enumerable.IsGenericType && Enumerable.GetGenericTypeDefinition() == typeof(IEnumerable<>)) return Enumerable.GetGenericArguments()[0];
foreach (Type interfaceType in Enumerable.GetInterfaces())
{
if (interfaceType.IsGenericType
&& interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
return interfaceType.GetGenericArguments()[0];
}
}
return null;
}
internal static bool IsValidTypePair(Type SrcPropertyType, Type DestPropertyType)
{
if (SrcPropertyType == DestPropertyType)
return true; //Simple Or Complex type
var t1 = GetGenericEnumerableType(SrcPropertyType);
var t2 = GetGenericEnumerableType(DestPropertyType);
if (t1 != null && t2 != null)
return true;
if (Mapper.Find(SrcPropertyType, DestPropertyType) != null)
return true;
return false;
}
internal static Expression Bind(PropertyInfo SrcPropertyInfo, PropertyInfo DestPropertyInfo, Expression ParameterExpression)
{
MemberExpression memberAccessExpr = null;
var mapType = GetMapType(SrcPropertyInfo, DestPropertyInfo);
switch (mapType)
{
case PropertyMapType.Simple:
return Expression.Property(ParameterExpression, SrcPropertyInfo);
case PropertyMapType.List:
var srcType = GetGenericEnumerableType(SrcPropertyInfo.PropertyType);
var destType = GetGenericEnumerableType(DestPropertyInfo.PropertyType);
var lambdaExpr = BuildExpression(srcType, destType);
memberAccessExpr = Expression.MakeMemberAccess(ParameterExpression, SrcPropertyInfo);
var selectCall = Expression.Call(typeof(Enumerable), "Select", new Type[] { srcType, destType }, memberAccessExpr, lambdaExpr);
return selectCall;
case PropertyMapType.Complex:
memberAccessExpr = Expression.Property(ParameterExpression, SrcPropertyInfo);
return BuildMemberInitExpression(SrcPropertyInfo.PropertyType, DestPropertyInfo.PropertyType, memberAccessExpr);
}
throw new Exception("Can't determine propertie's bind type");
}
internal static bool IsMapped(PropertyInfo SrcPropertyInfo, PropertyInfo DestPropertyInfo, string[] Expands)
{
var mapType = GetMapType(SrcPropertyInfo, DestPropertyInfo);
return mapType != PropertyMapType.Unmapped &&
(mapType != PropertyMapType.Complex && mapType != PropertyMapType.List || Expands.Select(p=>p.Split('/')[0]).Contains(DestPropertyInfo.Name));
}
private static PropertyMapType GetMapType(PropertyInfo SrcPropertyInfo, PropertyInfo DestPropertyInfo)
{
if (SrcPropertyInfo == null)
return PropertyMapType.Unmapped;
var srcType = SrcPropertyInfo.PropertyType;
var destType = DestPropertyInfo.PropertyType;
if (srcType == destType && Reflection.IsPrimitive(srcType))
//&& (srcType == typeof(string) || srcType.IsPrimitive || DataAvail. srcType.IsNu))
{
return PropertyMapType.Simple;
}
var t1 = TypeMap.GetGenericEnumerableType(srcType);
var t2 = TypeMap.GetGenericEnumerableType(destType);
if (t1 != null && t2 != null && Mapper.Find(t1, t2) != null)
return PropertyMapType.List;
if (Mapper.Find(srcType, destType) != null)
return PropertyMapType.Complex;
return PropertyMapType.Undefined;
}
private static Expression BuildExpression(Type SrcType, Type DestType)
{
var mapping = Mapper.Find(SrcType, DestType);
if (mapping == null)
throw new Exception(string.Format("Mapping between {0} and {1} not found", SrcType.Name, DestType.Name));
return mapping.BuildExpression();
}
private static Expression BuildMemberInitExpression(Type SrcType, Type DestType, Expression Expression)
{
var mapping = Mapper.Find(SrcType, DestType);
if (mapping == null)
throw new Exception(string.Format("Mapping between {0} and {1} not found", SrcType.Name, DestType.Name));
return mapping.BuildMemberInitExpression(Expression, new string[0]);
}
}
public enum PropertyMapType
{
Undefined,
Unmapped,
Simple,
Complex,
List,
Custom
}
}