/// <summary>Initializes a command service.</summary> /// <param name="client">WOLF client. Required.</param> /// <param name="options">Commands options that will be used as default when running a command. Required.</param> /// <param name="services">Services provider that will be used by all commands. Null will cause a backup provider to be used.</param> /// <param name="log">Logger to log messages and errors to. If null, all logging will be disabled.</param> /// <param name="cancellationToken">Cancellation token that can be used for cancelling all tasks.</param> public CommandsService(IWolfClient client, CommandsOptions options, ILogger log, IServiceProvider services = null, CancellationToken cancellationToken = default) { // init private this._commands = new Dictionary <ICommandInstanceDescriptor, ICommandInstance>(); this._lock = new SemaphoreSlim(1, 1); this._cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); this._disposableServices = new List <IDisposable>(2); this._started = false; // init required this._client = client ?? services?.GetService <IWolfClient>() ?? throw new ArgumentNullException(nameof(client)); this._options = options ?? services?.GetService <CommandsOptions>() ?? throw new ArgumentNullException(nameof(options)); // init optionals this._log = log ?? services?.GetService <ILogger <CommandsService> >() ?? services?.GetService <ILogger <ICommandsService> >() ?? services.GetService <ILogger>(); this._argumentConverterProvider = services?.GetService <IArgumentConverterProvider>() ?? CreateAsDisposable <ArgumentConverterProvider>(); this._handlerProvider = services?.GetService <ICommandsHandlerProvider>() ?? CreateAsDisposable <CommandsHandlerProvider>(); this._argumentsParser = services?.GetService <IArgumentsParser>() ?? new ArgumentsParser(); this._parameterBuilder = services?.GetService <IParameterBuilder>() ?? new ParameterBuilder(); this._initializers = services?.GetService <ICommandInitializerProvider>() ?? new CommandInitializerProvider(); this._commandsLoader = services?.GetService <ICommandsLoader>() ?? new CommandsLoader(this._initializers, this._log); // init service provider - use combine, to use fallback one as well this._fallbackServices = this.CreateFallbackServiceProvider(); this._services = CombinedServiceProvider.Combine(services, this._fallbackServices); // register event handlers this._client.AddMessageListener <ChatMessage>(OnMessageReceived); }
/// <summary>Attempts to convert argument to parameter type.</summary> /// <param name="parameter">Parameter to convert argument to.</param> /// <param name="argIndex">Index of argument.</param> /// <param name="values">Builder values. Must contain Args and ArgumentConverterProvider.</param> /// <param name="result">Result of the conversion. Null if conversion failed.</param> /// <param name="error">Exception that occured when converting. Null if there was no exception.</param> /// <returns>True if converting was successful; otherwise false.</returns> protected static bool TryConvertArgument(ParameterInfo parameter, int argIndex, ParameterBuilderValues values, out object result, out Exception error) { if (argIndex < 0) { throw new ArgumentException("Argument index cannot be negative", nameof(argIndex)); } if (values == null) { throw new ArgumentNullException(nameof(values)); } error = null; result = null; // check if we didn't run out of args if (values.Args == null || values.Args.Length - 1 < argIndex) { return(false); } // get from provider IArgumentConverterProvider provider = values.ArgumentConverterProvider; IArgumentConverter converter = provider?.GetConverter(parameter); if (converter == null) { return(false); } try { result = converter.Convert(parameter, values.Args[argIndex]); return(true); } catch (Exception ex) { error = ex; return(false); } }