Пример #1
0
        private void RegisterControllerInternal(Type controllerType, CommandControllerBase controller)
        {
            if (_registeredControllerTypes.Contains(controllerType))
            {
                throw new ArgumentException("A controller of the same type has already been registered.", nameof(controllerType));
            }
            if (_dependencyResolver == null && !controllerType.GetConstructors().Any(c => c.GetParameters().Length == 0))
            {
                throw new ArgumentException("The type of controller does not have a parameterless constructor and no dependency controller is used for this service.", nameof(controllerType));
            }

            string prefix = string.Empty;
            bool   controllerCaseSensitive = false;
            bool   instantiatePerCommand   = false;

            CommandControllerAttribute controllerAttribute = controllerType.GetCustomAttributes(typeof(CommandControllerAttribute), true).FirstOrDefault() as CommandControllerAttribute;

            if (controllerAttribute != null)
            {
                prefix = controllerAttribute.Prefix;
                controllerCaseSensitive = controllerAttribute.CaseSensitiveRouting;
                instantiatePerCommand   = controller == null ? controllerAttribute.InstantiatePerExecutedCommand : false;
            }

            const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;

            foreach (MethodInfo method in controllerType.GetMethods(flags))
            {
                foreach (CommandAttribute attribute in method.GetCustomAttributes(typeof(CommandAttribute), true))
                {
                    string fullRoute = attribute.UseControllerPrefix
                        ? prefix + attribute.Route
                        : attribute.Route;

                    CommandData commandData = new CommandData
                    {
                        Arguments = method.GetParameters()
                                    .Select(p => new CommandArgument {
                            Name = p.Name, Type = p.ParameterType
                        })
                                    .ToList(),
                        CaseSensitive = attribute.IsCaseSensitiveRoutingSet ? attribute.CaseSensitiveRouting : controllerCaseSensitive,
                        InstantiatePerExecutedCommand = instantiatePerCommand,
                        ControllerType     = controllerType,
                        ControllerInstance = controller,
                        Method             = method,
                        RouteParts         = CommandRouteParser.GetRouteParts(fullRoute),
                        Description        = attribute.Description
                    };

                    _commandDataCollection.Add(commandData);
                }
            }

            _registeredControllerTypes.Add(controllerType);
        }
Пример #2
0
        /// <summary>
        /// Executes the specified command line.
        /// </summary>
        /// <param name="commandLine">The command line.</param>
        /// <returns>Result information as a <see cref="CommandResult"/> object.</returns>
        /// <exception cref="CommandException">A detailed exception wrapper, thrown when execution goes wrong.</exception>
        public CommandResult Execute(string commandLine)
        {
            if (string.IsNullOrEmpty(commandLine))
            {
                throw new CommandException("No command line specified.", commandLine, CommandErrorCode.EmptyInput, null);
            }

            lock (_syncRoot)
            {
                foreach (CommandData commandData in _commandDataCollection)
                {
                    Dictionary <string, string> argumentValues;
                    if (CommandRouteParser.TryParseCommandLine(commandLine, commandData.RouteParts, commandData.CaseSensitive, out argumentValues))
                    {
                        int      argumentCount   = commandData.Arguments.Count;
                        object[] parsedArguments = new object[argumentCount];

                        for (int i = 0; i < argumentCount; i++)
                        {
                            CommandArgument argumentData = commandData.Arguments[i];
                            string          argumentValue;

                            ICommandArgumentParser argumentParser;

                            if (!argumentValues.TryGetValue(argumentData.Name, out argumentValue))
                            {
                                parsedArguments[i] = argumentData.Type.IsValueType
                                    ? Activator.CreateInstance(argumentData.Type)
                                    : null;
                            }
                            else if (_argumentParsers.TryGetValue(argumentData.Type, out argumentParser))
                            {
                                try
                                {
                                    parsedArguments[i] = argumentParser.Parse(argumentData.Name, argumentValue);
                                }
                                catch (Exception ex)
                                {
                                    throw new CommandException(commandLine, "An argument parser threw an exception.", CommandErrorCode.ArgumentParseError, ex);
                                }
                            }
                            else if (typeof(IConvertible).IsAssignableFrom(argumentData.Type))
                            {
                                try
                                {
                                    parsedArguments[i] = Convert.ChangeType(argumentValue, argumentData.Type);
                                }
                                catch (Exception ex)
                                {
                                    throw new CommandException(commandLine, "There was an error converting an argument.", CommandErrorCode.ArgumentParseError, ex);
                                }
                            }
                            else
                            {
                                throw new CommandException(commandLine, $"Could not find a way to parse argument '{argumentData.Name}'.", CommandErrorCode.ArgumentParseError, null);
                            }
                        }

                        CommandControllerBase controller = null;

                        if (commandData.InstantiatePerExecutedCommand)
                        {
                            controller = InstantiateController(commandData.ControllerType);
                        }
                        else if (commandData.ControllerInstance == null)
                        {
                            commandData.ControllerInstance = controller = InstantiateController(commandData.ControllerType);
                        }
                        else
                        {
                            controller = commandData.ControllerInstance;
                        }

                        controller.CommandServiceInternal = this;
                        controller.CommandLineInternal    = commandLine;
                        controller.LastResultInternal     = _lastResult;

                        try
                        {
                            _lastResult = commandData.Method.Invoke(controller, parsedArguments);
                        }
                        catch (Exception ex)
                        {
                            throw new CommandException("An error occured while executing the command method.", commandLine, CommandErrorCode.CommandError, ex);
                        }

                        return(new CommandResult(_lastResult, controller.GetType(), commandData.Method));
                    }
                }

                throw new CommandException("No route matched the input.", commandLine, CommandErrorCode.UnknownCommand, null);
            }
        }