/// <summary> /// Maps the methods of the given <see cref="CommandControllerBase" /> instance to their respective methods, using the <see cref="CommandAttribute" /> attribute. /// Ignores the <see cref="CommandControllerAttribute.InstantiatePerExecutedCommand" /> setting and reuses the given <see cref="CommandControllerBase" /> instance for each command. /// </summary> /// <param name="controller">The <see cref="CommandControllerBase" /> containing the methods to register.</param> /// <exception cref="ArgumentNullException"><paramref name="controller"/> is <c>null</c>.</exception> public void RegisterControllerConstant(CommandControllerBase controller) { if (controller == null) { throw new ArgumentNullException(nameof(controller), "'controller' cannot be null."); } lock (_syncRoot) { RegisterControllerInternal(controller.GetType(), controller); } }
/// <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); } }