コード例 #1
0
ファイル: CommandBinder.cs プロジェクト: ironch/Typin
        /// <summary>
        /// Binds parameter inputs in command instance.
        /// </summary>
        public static void BindParameters(this CommandSchema commandSchema, ICommand instance, IReadOnlyList <CommandParameterInput> parameterInputs)
        {
            IReadOnlyList <CommandParameterSchema> parameters = commandSchema.Parameters;

            // All inputs must be bound
            int remainingParameters = parameters.Count;
            int remainingInputs     = parameterInputs.Count;

            if (remainingParameters > remainingInputs)
            {
                throw ArgumentBindingExceptions.ParameterNotSet(parameters.TakeLast(remainingParameters - remainingInputs));
            }

            // Scalar parameters
            int i = 0;

            for (; i < parameters.Count && parameters[i].IsScalar; ++i)
            {
                CommandParameterSchema parameter   = parameters[i];
                CommandParameterInput  scalarInput = parameterInputs[i];

                parameter.BindOn(instance, scalarInput.Value);

                --remainingParameters;
                --remainingInputs;
            }

            // Non-scalar parameter (only one is allowed)
            if (i < parameters.Count && !parameters[i].IsScalar)
            {
                CommandParameterSchema nonScalarParameter = parameters[i];

                string[] nonScalarValues = parameterInputs.TakeLast(remainingInputs)
                                           .Select(p => p.Value)
                                           .ToArray();

                // Parameters are required by default and so a non-scalar parameter must be bound to at least one value
                if (!nonScalarValues.Any())
                {
                    throw ArgumentBindingExceptions.ParameterNotSet(new[] { nonScalarParameter });
                }

                nonScalarParameter.BindOn(instance, nonScalarValues);
                --remainingParameters;
                remainingInputs = 0;
            }

            // Ensure all inputs were bound
            if (remainingInputs > 0)
            {
                throw ArgumentBindingExceptions.UnrecognizedParametersProvided(parameterInputs.TakeLast(remainingInputs));
            }
        }
コード例 #2
0
        public async Task HandleAsync(ICliContext context, CommandPipelineHandlerDelegate next, CancellationToken cancellationToken)
        {
            //Get current CLI mode and input directives
            Type currentModeType = _applicationLifetime.CurrentModeType !;
            IReadOnlyList <DirectiveInput> directives = context.Input.Directives;

            //Initialize collections
            List <IDirective>          directivesInstances          = new List <IDirective>();
            List <IPipelinedDirective> pipelinedDirectivesInstances = new List <IPipelinedDirective>();

            //Process directive input
            foreach (DirectiveInput directiveInput in directives)
            {
                // Try to get the directive matching the input or fallback to default
                DirectiveSchema directive = context.RootSchema.TryFindDirective(directiveInput.Name) ?? throw ArgumentBindingExceptions.UnknownDirectiveName(directiveInput);

                // Handle interactive directives not supported in current mode
                if (!directive.CanBeExecutedInMode(currentModeType))
                {
                    throw ModeEndUserExceptions.DirectiveExecutedInInvalidMode(directive, currentModeType);
                }

                // Get directive instance
                IDirective instance = (IDirective)_serviceProvider.GetRequiredService(directive.Type);

                //Initialize directive
                await instance.OnInitializedAsync(cancellationToken);

                //Add directive to list
                directivesInstances.Add(instance);

                if (directive.IsPipelinedDirective && instance is IPipelinedDirective pd)
                {
                    pipelinedDirectivesInstances.Add(pd);
                }
            }

            //Set directives lists in context
            CliContext internalCliContext = (CliContext)context;

            internalCliContext.Directives          = directivesInstances;
            internalCliContext.PipelinedDirectives = pipelinedDirectivesInstances;

            await next();
        }