forked from ThatRendle/Simple.Data
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAdapterMethodDynamicInvoker.cs
More file actions
92 lines (82 loc) · 3.15 KB
/
AdapterMethodDynamicInvoker.cs
File metadata and controls
92 lines (82 loc) · 3.15 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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Simple.Data
{
using System.Dynamic;
using System.Reflection;
internal class AdapterMethodDynamicInvoker
{
private readonly Adapter _adapter;
public AdapterMethodDynamicInvoker(Adapter adapter)
{
_adapter = adapter;
}
public bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var adapterMethods = _adapter.GetType().GetMethods().Where(m => m.Name == binder.Name).ToList();
foreach (var method in adapterMethods)
{
var parameters = method.GetParameters().ToArray();
if (parameters.Any(p => p.RawDefaultValue != DBNull.Value) && binder.CallInfo.ArgumentNames.Any(s => !string.IsNullOrWhiteSpace(s)))
{
if (TryInvokeMemberWithNamedParameters(binder, args, out result, method, parameters))
{
return true;
}
}
else
{
if (AreCompatible(parameters, args))
{
result = method.Invoke(_adapter, args);
return true;
}
}
}
result = null;
return false;
}
private bool TryInvokeMemberWithNamedParameters(InvokeMemberBinder binder, object[] args, out object result,
MethodInfo method, ParameterInfo[] parameters)
{
var fixedArgs = new List<object>();
for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i].RawDefaultValue == DBNull.Value)
{
fixedArgs.Add(args[i]);
}
else
{
var index = binder.CallInfo.ArgumentNames.IndexOf(parameters[i].Name);
if (index > -1)
{
if (!parameters[i].ParameterType.IsInstanceOfType(args[index]))
{
result = null;
return false;
}
}
else
{
fixedArgs.Add(parameters[i].RawDefaultValue);
}
}
}
result = method.Invoke(_adapter, fixedArgs.ToArray());
return true;
}
private static bool AreCompatible(IList<ParameterInfo> parameters, IList<object> args)
{
if (parameters.Count != args.Count) return false;
for (int i = 0; i < parameters.Count; i++)
{
if (ReferenceEquals(args[i], null)) return !parameters[i].ParameterType.IsValueType;
if (!parameters[i].ParameterType.IsInstanceOfType(args[i])) return false;
}
return true;
}
}
}