void AddBindDestionations(CommandParameterDiscovery parameterDiscovery, object destination) { foreach (var parameter in parameterDiscovery.NamedParameters.Values) { _bindDestinationLookup[parameter.MemberInfo] = destination; } }
internal void AddParametersToAllSets(CommandParameterDiscovery discovery) { // add the parameters to all sets var updatedParameterSets = new List<CommandParameterSetInfo>(); foreach (CommandParameterSetInfo parameterSet in ParameterSets) { List<CommandParameterInfo> updatedParameters = parameterSet.Parameters.ToList(); updatedParameters.AddRange(discovery.AllParameters); updatedParameterSets.Add(new CommandParameterSetInfo( parameterSet.Name, parameterSet.IsDefault, new Collection<CommandParameterInfo>(updatedParameters))); } ParameterSets = new ReadOnlyCollection<CommandParameterSetInfo>(updatedParameterSets); // register all parameter names in the lookup table foreach (var namedParameter in discovery.NamedParameters.Values) { RegisterParameterInLookupTable(namedParameter); } }
private CommandParameterCollection BindDynamicParameters(CommandParameterCollection parameters) { var dynamicParamsCmdlet = _cmdlet as IDynamicParameters; if (dynamicParamsCmdlet == null) // no support for dynamic parameters { return parameters; } // get the object with dynamic parameters var parameterObject = dynamicParamsCmdlet.GetDynamicParameters(); if (parameterObject == null) { return parameters; } var discovery = new CommandParameterDiscovery(parameterObject.GetType()); // add the parameters to the cmdletInfo _cmdletInfo.AddParametersToAllSets(discovery); // as we updated parameter sets, we need to rebuild some cached values _activeSet = _activeSet == null ? null : GetParameterSet(_activeSet.Name); _defaultSet = _defaultSet == null ? null : GetParameterSet(_defaultSet.Name); _candidateParameterSets = (from p in _candidateParameterSets select GetParameterSet(p.Name)).ToList(); AddBindDestionations(discovery, parameterObject); // now try to rebind the parameters parameters = BindNamedParameters(parameters); return BindPositionalParameters(parameters, ActiveOrDefaultParameterSet); }
/// <remarks> /// From MSDN article: http://msdn2.microsoft.com/en-us/library/ms714348(VS.85).aspx /// /// * A cmdlet can have any number of parameters. However, for a better user experience the number /// of parameters should be limited when possible. /// * Parameters must be declared on public non-static fields or properties. It is preferred for /// parameters to be declared on properties. The property must have a public setter, and if ValueFromPipeline /// or ValueFromPipelineByPropertyName is specified the property must have a public getter. /// * When specifying positional parameters, note the following. /// * Limit the number of positional parameters in a parameter set to less than five if possible. /// * Positional parameters do not have to be sequential; positions 5, 100, 250 works the same as positions 0, 1, 2. /// * When the Position keyword is not specified, the cmdlet parameter must be referenced by its name. /// * When using parameter sets, no parameter set should contain more than one positional parameter with the same position. /// * In addition, only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true. /// /// </remarks> private void InitializeParameterSetInfo(Type cmdletType) { Dictionary<string, Collection<CommandParameterInfo>> paramSets = new Dictionary<string, Collection<CommandParameterInfo>>(StringComparer.CurrentCultureIgnoreCase); // TODO: When using parameter sets, no parameter set should contain more than one positional parameter with the same position. // TODO: If not parameters have a position declared then positions for all the parameters should be automatically declaredin the order they are specified // TODO: Only one parameter in a set should declare ValueFromRemainingArguments = true // TODO: Only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true. // TODO: Currently due to the way parameters are loaded into sets from all set at the end the parameter end up in incorrect order. // get the name of the default parameter set string strDefaultParameterSetName = null; object[] cmdLetAttrs = cmdletType.GetCustomAttributes(typeof(CmdletAttribute), false); if (cmdLetAttrs.Length > 0) { strDefaultParameterSetName = ((CmdletAttribute)cmdLetAttrs[0]).DefaultParameterSetName; // If a default set is specified, it has to exist, even if it's empty. // See NonExisitingDefaultParameterSetIsEmptyPatameterSet reference test if (!String.IsNullOrEmpty(strDefaultParameterSetName)) { paramSets.Add(strDefaultParameterSetName, new Collection<CommandParameterInfo>()); } } // always have a parameter set for all parameters. even if we don't have any parameters or no parameters // that are in all sets. This will nevertheless save various checks if (!paramSets.ContainsKey(ParameterAttribute.AllParameterSets)) { paramSets.Add(ParameterAttribute.AllParameterSets, new Collection<CommandParameterInfo>()); } var parameterDiscovery = new CommandParameterDiscovery(cmdletType); // first add the parameters to the parameter sets foreach (var parameter in parameterDiscovery.AllParameters) { AddParameterToParameterSet(paramSets, parameter); } // now add each parameter member to the lookup table foreach (var namedParam in parameterDiscovery.NamedParameters.Values) { RegisterParameterInLookupTable(namedParam); } // Create param-sets collection. Add the parameters from the AllParameterSets set to all other sets Collection<CommandParameterSetInfo> paramSetInfo = new Collection<CommandParameterSetInfo>(); foreach (string paramSetName in paramSets.Keys) { // If a parameter set is not specified for a parmeter, then the parameter belongs to all the parameter sets, // therefore if this is not the AllParameterSets Set then add all parameters from the AllParameterSets Set to it... if (!paramSetName.Equals(ParameterAttribute.AllParameterSets)) { foreach (CommandParameterInfo cpi in paramSets[ParameterAttribute.AllParameterSets]) { paramSets[paramSetName].Add(cpi); } } // add the set to the setInfo collection bool bIsDefaultParamSet = paramSetName.Equals(strDefaultParameterSetName); paramSetInfo.Add(new CommandParameterSetInfo(paramSetName, bIsDefaultParamSet, paramSets[paramSetName])); } ParameterSets = new ReadOnlyCollection<CommandParameterSetInfo>(paramSetInfo); // last, but not least, at all common parameters to all parameter sets AddParametersToAllSets(CommonCmdletParameters.ParameterDiscovery); }