Example #1
0
 void AddBindDestionations(CommandParameterDiscovery parameterDiscovery, object destination)
 {
     foreach (var parameter in parameterDiscovery.NamedParameters.Values)
     {
         _bindDestinationLookup[parameter.MemberInfo] = destination;
     }
 }
Example #2
0
        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);
            }
        }
Example #3
0
        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);
        }
Example #4
0
        /// <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);
        }