public async Task <IResult> ExecuteAsync(ITurnContext context, IEnumerable <object> argList, IEnumerable <object> paramList, IServiceProvider services) { services = services ?? EmptyServiceProvider.Instance; try { object[] args = GenerateArgs(argList, paramList); for (int position = 0; position < Parameters.Count; position++) { var parameter = Parameters[position]; object argument = args[position]; var result = await parameter.CheckPreconditionsAsync(context, argument, services).ConfigureAwait(false); if (!result.IsSuccess) { return(ExecuteResult.FromError(result)); } } switch (RunMode) { case RunMode.Sync: //Always sync return(await ExecuteInternalAsync(context, args, services).ConfigureAwait(false)); case RunMode.Async: //Always async var t2 = Task.Run(async() => { await ExecuteInternalAsync(context, args, services).ConfigureAwait(false); }); break; } return(ExecuteResult.FromSuccess()); } catch (Exception ex) { return(ExecuteResult.FromError(ex)); } }
private async Task <IResult> ExecuteInternalAsync(ITurnContext context, object[] args, IServiceProvider services) { //await Module.Service._cmdLogger.DebugAsync($"Executing {GetLogText(context)}").ConfigureAwait(false); try { var task = _action(context, args, services, this); if (task is Task <IResult> resultTask) { var result = await resultTask.ConfigureAwait(false); await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result).ConfigureAwait(false); if (result is RuntimeResult execResult) { return(execResult); } } else if (task is Task <ExecuteResult> execTask) { var result = await execTask.ConfigureAwait(false); await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result).ConfigureAwait(false); return(result); } else { await task.ConfigureAwait(false); var result = ExecuteResult.FromSuccess(); await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result).ConfigureAwait(false); } var executeResult = ExecuteResult.FromSuccess(); return(executeResult); } catch (Exception ex) { var originalEx = ex; while (ex is TargetInvocationException) //Happens with void-returning commands { ex = ex.InnerException; } var wrappedEx = new CommandException(this, context, ex); await Module.Service._cmdLogger.ErrorAsync(wrappedEx).ConfigureAwait(false); var result = ExecuteResult.FromError(ex); if (Module.Service._throwOnError) { if (ex == originalEx) { throw; } else { ExceptionDispatchInfo.Capture(ex).Throw(); } } return(result); } finally { //TODO add login back -- //await Module.Service._cmdLogger.VerboseAsync($"Executed {GetLogText(context)}").ConfigureAwait(false); } }
private static void BuildCommand(CommandBuilder builder, TypeInfo typeInfo, MethodInfo method, CommandService service, IServiceProvider serviceprovider) { var attributes = method.GetCustomAttributes(); foreach (var attribute in attributes) { switch (attribute) { case CommandAttribute command: builder.AddAliases(command.Text); builder.RunMode = command.RunMode; builder.Name = builder.Name ?? command.Text; builder.IgnoreExtraArgs = command.IgnoreExtraArgs ?? service._ignoreExtraArgs; break; case NameAttribute name: builder.Name = name.Text; break; case PriorityAttribute priority: builder.Priority = priority.Priority; break; case SummaryAttribute summary: builder.Summary = summary.Text; break; case RemarksAttribute remarks: builder.Remarks = remarks.Text; break; case AliasAttribute alias: builder.AddAliases(alias.Aliases); break; case PreconditionAttribute precondition: builder.AddPrecondition(precondition); break; default: builder.AddAttributes(attribute); break; } } if (builder.Name == null) { builder.Name = method.Name; } var parameters = method.GetParameters(); int pos = 0, count = parameters.Length; foreach (var paramInfo in parameters) { builder.AddParameter((parameter) => { BuildParameter(parameter, paramInfo, pos++, count, service, serviceprovider); }); } var createInstance = ReflectionUtils.CreateBuilder <IModuleBase>(typeInfo, service); async Task <IResult> ExecuteCallback(ITurnContext context, object[] args, IServiceProvider services, CommandInfo cmd) { var instance = createInstance(services); instance.SetContext(context); try { instance.BeforeExecute(cmd); var task = method.Invoke(instance, args) as Task ?? Task.Delay(0); if (task is Task <RuntimeResult> resultTask) { return(await resultTask.ConfigureAwait(false)); } else { await task.ConfigureAwait(false); return(ExecuteResult.FromSuccess()); } } finally { instance.AfterExecute(cmd); (instance as IDisposable)?.Dispose(); } } builder.Callback = ExecuteCallback; }