指定另一个参数时未调用 GetDynamicParameters()
GetDynamicParameters() not invoked when another parameter is specified
我正在用 C# 开发一个 PowerShell cmdlet Get-Foo
,它定义了一个 dynamic parameter Bar
,它应该只在指定开关参数 MySwitch
时显示。它还具有其他参数 MyString
、MyInt
和 MyBool
。
当我 运行 cmdlet 时,当我指定开关参数 MySwitch
以及 MyString
或MyInt
但当我将它与 MyBool
(或任何其他参数类型)一起使用时则不会。
代码如下:
namespace MyCompany.Cmdlets
{
[Cmdlet(VerbsCommon.Get, "Foo")]
public class GetFoo : PSCmdlet, IDynamicParameters
{
[Parameter]
public string MyString { get; set; }
[Parameter]
public int MyInt { get; set; }
[Parameter]
public bool MyBool { get; set; }
[Parameter]
public SwitchParameter MySwitch { get; set; }
public object GetDynamicParameters()
{
if (MySwitch.IsPresent)
{
context = new FooParameters();
return context;
}
return null;
}
private FooParameters context;
protected override void ProcessRecord() {}
}
public class FooParameters
{
[Parameter]
public string Bar { get; set; }
}
}
我做错了什么?如何在指定 MyBool
参数(或 MyObject
参数)时显示动态参数?
当使用结构 "SwitchParameter" 时,我像对待任何其他布尔值一样对待它,例如:
if (MySwitchParameter)
{
// la la la other stuff
}
GetDynamicParameters 很棘手,但是,就 Return 而言,您有两个选择
值:Return一个代表你的参数的对象ORreturn一个
RuntimeDefinedParameterDictionary 对象。想想 RuntimeDefinedParameterDictionary
作为表达参数的 "CodeDom-Like" 方式。
这里可能重写了您的 Get-Foo Cmdlet,重点放在动态参数上:
[Cmdlet(VerbsCommon.Get, "Foo",
SupportsShouldProcess = true
)]
public class GetFooCommand : PSCmdlet, IDynamicParameters
{
// First things first: Lets try making a dictionary for our return
// value in our implementation of IDynamicParameter's
// GetDynamicParameters() method
private RuntimeDefinedParameterDictionary DynamicParameters;
[Parameter]
public string MyString { get; set; }
[Parameter]
public int MyInt { get; set; }
[Parameter]
// Booleans are not as fun as SwitchParameters, IMHO
public bool MyBool { get; set; }
// Remember that SwitchParameter is really just a boolean (sort of), so
// it will default to 'false'
[Parameter]
public SwitchParameter MySwitch { get; set; }
public object GetDynamicParameters()
{
// You only want this to run when the switch is flipped,
// so try it this way and see if it works for you
if (MySwitch)
{
// Create the dictionary. We will return this at the end because
// **** spoiler alert **** it is an object :)
var runtimeParameterDictionary = new RuntimeDefinedParameterDictionary();
// Lets make that parameter now. Your example doesn't specify any
// additional parameter attributes beyond the required "ParameterAttribute",
// so here we create an empty Attribute Collection
var runtimeParameter =
new RuntimeDefinedParameter("Bar", typeof (string), new Collection<Attribute>());
// With a new Parameter, lets add it to our dictionary.
runtimeParameterDictionary.Add("Bar", runtimeParameter);
// Because we created a field for our dictionary way up top, we can assign it like I
// illustrate below. This will enable easy, predictable results when we seek to
// extract the values from the dictionary at runtime.
DynamicParameters = runtimeParameterDictionary;
// Note: You can add as many parameters as you want this way, and that Is
// why I recommend it to you now. Coding the parameters as classes outside of the
// Cmdlet, and to some extent as embedded Classes,
// within the Cmdlet Never really worked for me, so I feel your pain/frustration.
return runtimeParameterDictionary;
}
return null; // Guess the user doesn't want that Bar afterall;
}
protected override void ProcessRecord()
{
// We obviously want to sequester everything we are doing with the dynamic
// parameters so a good-old-fashioned if.. then.. else... will suffice.
if (MySwitch)
{
// Now we are here at the precipice of this DynamicParameter cmdlet.
// Here is one way to get the value desired from the dynamic parameter.
// Simply access it like a dictionary...
var bar = DynamicParameters["Bar"].Value as string;
// The reason we can do it this way is because we assigned our
// beloved value to the local variable "DynmaicParameters"
// in the GetDynamicParameters() method. We could care less about
// the return value, because if the
// switch is flipped, "DynamicParameters" will be our new best friend, and
// it will have everything we need.
WriteWarning("Your " + bar + " has been forwarded to an automatic voice messaging system ...");
}
WriteObject("Cheers was filmed before a live studio audience...");
WriteObject(MyInvocation.BoundParameters);
}
}
我正在用 C# 开发一个 PowerShell cmdlet Get-Foo
,它定义了一个 dynamic parameter Bar
,它应该只在指定开关参数 MySwitch
时显示。它还具有其他参数 MyString
、MyInt
和 MyBool
。
当我 运行 cmdlet 时,当我指定开关参数 MySwitch
以及 MyString
或MyInt
但当我将它与 MyBool
(或任何其他参数类型)一起使用时则不会。
代码如下:
namespace MyCompany.Cmdlets
{
[Cmdlet(VerbsCommon.Get, "Foo")]
public class GetFoo : PSCmdlet, IDynamicParameters
{
[Parameter]
public string MyString { get; set; }
[Parameter]
public int MyInt { get; set; }
[Parameter]
public bool MyBool { get; set; }
[Parameter]
public SwitchParameter MySwitch { get; set; }
public object GetDynamicParameters()
{
if (MySwitch.IsPresent)
{
context = new FooParameters();
return context;
}
return null;
}
private FooParameters context;
protected override void ProcessRecord() {}
}
public class FooParameters
{
[Parameter]
public string Bar { get; set; }
}
}
我做错了什么?如何在指定 MyBool
参数(或 MyObject
参数)时显示动态参数?
当使用结构 "SwitchParameter" 时,我像对待任何其他布尔值一样对待它,例如:
if (MySwitchParameter)
{
// la la la other stuff
}
GetDynamicParameters 很棘手,但是,就 Return 而言,您有两个选择 值:Return一个代表你的参数的对象ORreturn一个 RuntimeDefinedParameterDictionary 对象。想想 RuntimeDefinedParameterDictionary 作为表达参数的 "CodeDom-Like" 方式。
这里可能重写了您的 Get-Foo Cmdlet,重点放在动态参数上:
[Cmdlet(VerbsCommon.Get, "Foo",
SupportsShouldProcess = true
)]
public class GetFooCommand : PSCmdlet, IDynamicParameters
{
// First things first: Lets try making a dictionary for our return
// value in our implementation of IDynamicParameter's
// GetDynamicParameters() method
private RuntimeDefinedParameterDictionary DynamicParameters;
[Parameter]
public string MyString { get; set; }
[Parameter]
public int MyInt { get; set; }
[Parameter]
// Booleans are not as fun as SwitchParameters, IMHO
public bool MyBool { get; set; }
// Remember that SwitchParameter is really just a boolean (sort of), so
// it will default to 'false'
[Parameter]
public SwitchParameter MySwitch { get; set; }
public object GetDynamicParameters()
{
// You only want this to run when the switch is flipped,
// so try it this way and see if it works for you
if (MySwitch)
{
// Create the dictionary. We will return this at the end because
// **** spoiler alert **** it is an object :)
var runtimeParameterDictionary = new RuntimeDefinedParameterDictionary();
// Lets make that parameter now. Your example doesn't specify any
// additional parameter attributes beyond the required "ParameterAttribute",
// so here we create an empty Attribute Collection
var runtimeParameter =
new RuntimeDefinedParameter("Bar", typeof (string), new Collection<Attribute>());
// With a new Parameter, lets add it to our dictionary.
runtimeParameterDictionary.Add("Bar", runtimeParameter);
// Because we created a field for our dictionary way up top, we can assign it like I
// illustrate below. This will enable easy, predictable results when we seek to
// extract the values from the dictionary at runtime.
DynamicParameters = runtimeParameterDictionary;
// Note: You can add as many parameters as you want this way, and that Is
// why I recommend it to you now. Coding the parameters as classes outside of the
// Cmdlet, and to some extent as embedded Classes,
// within the Cmdlet Never really worked for me, so I feel your pain/frustration.
return runtimeParameterDictionary;
}
return null; // Guess the user doesn't want that Bar afterall;
}
protected override void ProcessRecord()
{
// We obviously want to sequester everything we are doing with the dynamic
// parameters so a good-old-fashioned if.. then.. else... will suffice.
if (MySwitch)
{
// Now we are here at the precipice of this DynamicParameter cmdlet.
// Here is one way to get the value desired from the dynamic parameter.
// Simply access it like a dictionary...
var bar = DynamicParameters["Bar"].Value as string;
// The reason we can do it this way is because we assigned our
// beloved value to the local variable "DynmaicParameters"
// in the GetDynamicParameters() method. We could care less about
// the return value, because if the
// switch is flipped, "DynamicParameters" will be our new best friend, and
// it will have everything we need.
WriteWarning("Your " + bar + " has been forwarded to an automatic voice messaging system ...");
}
WriteObject("Cheers was filmed before a live studio audience...");
WriteObject(MyInvocation.BoundParameters);
}
}