// executes the step internal async Task <InstallSetupResult> ExecuteStepAsync(InstallSetupStep step, object instruction) { using (_proflog.TraceDuration <InstallApiController>($"Executing installation step: '{step.Name}'.", "Step completed")) { var modelAttempt = instruction.TryConvertTo(step.StepType); if (!modelAttempt.Success) { throw new InvalidCastException( $"Cannot cast/convert {step.GetType().FullName} into {step.StepType.FullName}"); } var model = modelAttempt.Result; var genericStepType = typeof(InstallSetupStep <>); Type[] typeArgs = { step.StepType }; var typedStepType = genericStepType.MakeGenericType(typeArgs); try { var method = typedStepType.GetMethods().Single(x => x.Name == "ExecuteAsync"); var task = (Task <InstallSetupResult>)method.Invoke(step, new[] { model }); return(await task); } catch (Exception ex) { _logger.LogError(ex, "Installation step {Step} failed.", step.Name); throw; } } }
// determines whether the step requires execution internal bool StepRequiresExecution(InstallSetupStep step, object instruction) { if (step == null) { throw new ArgumentNullException(nameof(step)); } var modelAttempt = instruction.TryConvertTo(step.StepType); if (!modelAttempt.Success) { throw new InvalidCastException( $"Cannot cast/convert {step.GetType().FullName} into {step.StepType.FullName}"); } var model = modelAttempt.Result; var genericStepType = typeof(InstallSetupStep <>); Type[] typeArgs = { step.StepType }; var typedStepType = genericStepType.MakeGenericType(typeArgs); try { var method = typedStepType.GetMethods().Single(x => x.Name == "RequiresExecution"); return((bool)method.Invoke(step, new[] { model })); } catch (Exception ex) { _logger.LogError(ex, "Checking if step requires execution ({Step}) failed.", step.Name); throw; } }