-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathDynamicParameterExtension.cs
111 lines (95 loc) · 3.66 KB
/
DynamicParameterExtension.cs
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
using ExposedObject;
using System;
using System.Globalization;
using System.Management.Automation;
using System.Reflection;
// Originally taken from https://stackoverflow.com/a/35196839/794962
namespace Meadow.Cli
{
public static class DynamicParameterExtension
{
/// <summary>
/// Gets the private variable of type System.Management.Automation.ExecutionContext
/// </summary>
public static object GetExecutionContext(this PSCmdlet cmdlet)
{
var context = Exposed.From(cmdlet).Context;
return context;
}
public static T GetUnboundValue<T>(this PSCmdlet cmdlet, string paramName, int unnamedPosition = -1)
{
var context = GetExecutionContext(cmdlet);
var processor = Exposed.From(context).CurrentCommandProcessor;
var parameterBinder = Exposed.From(processor).CmdletParameterBinderController;
var args = Exposed.From(parameterBinder).UnboundArguments as System.Collections.IEnumerable;
if (args != null)
{
var isSwitch = typeof(SwitchParameter) == typeof(T);
var currentParameterName = string.Empty;
object unnamedValue = null;
var i = 0;
foreach (var arg in args)
{
var isParameterName = Exposed.From(arg).ParameterNameSpecified;
if (isParameterName != null && true.Equals(isParameterName))
{
var parameterName = Exposed.From(arg).ParameterName as string;
currentParameterName = parameterName;
if (isSwitch && string.Equals(currentParameterName, paramName, StringComparison.OrdinalIgnoreCase))
{
return (T)(object)new SwitchParameter(true);
}
continue;
}
var parameterValue = Exposed.From(arg).ArgumentValue;
if (!string.IsNullOrEmpty(currentParameterName))
{
if (string.Equals(currentParameterName, paramName, StringComparison.OrdinalIgnoreCase))
{
return ConvertParameter<T>(parameterValue);
}
}
else if (i++ == unnamedPosition)
{
unnamedValue = parameterValue;
}
currentParameterName = string.Empty;
}
if (unnamedValue != null)
{
return ConvertParameter<T>(unnamedValue);
}
}
return default;
}
static T ConvertParameter<T>(this object value)
{
if (value == null || Equals(value, default(T)))
{
return default;
}
var psObject = value as PSObject;
if (psObject != null)
{
return psObject.BaseObject.ConvertParameter<T>();
}
if (value is T)
{
return (T)value;
}
var constructorInfo = typeof(T).GetConstructor(new[] { value.GetType() });
if (constructorInfo != null)
{
return (T)constructorInfo.Invoke(new[] { value });
}
try
{
return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
}
catch (Exception)
{
return default;
}
}
}
}