public Workflow(Model.WorkflowDefinition workflowDefinition, params Assembly[] frameworkExtensionsAssemblies) { this.WorkflowDefinition = workflowDefinition; //Validate and build worfklow steps foreach (Model.StepDefinition step in workflowDefinition.Steps) { //Find concrete step class decorated by "StepAttribute" with the step type commming from workflow definition Type stepType = frameworkExtensionsAssemblies .ScanTypesForCustomAttributes((StepAttribute attribute) => attribute.Type == step.Type) .SingleOrDefault(); if (stepType == null) { throw new InvalidOperationException($@"The worfklow step type ""{step.Type}"" was not found in registered framework extensions"); } Type stepInterfaceType = stepType.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IStep <>)).FirstOrDefault(); //Create a concrete step instance if (stepInterfaceType != null) { Type paramType = stepInterfaceType.GetGenericArguments().Single(); object paramValue; if (step.Param.GetType() == paramType) { paramValue = step.Param; } else if (step.Param is JToken jtoken) { paramValue = jtoken.ToObject(paramType); } else { throw new NotSupportedException($@"Step ""{step.Type}"" has invalid ""Param"" property type ""{step.Param.GetType()}"""); } IStep stepInstance = (IStep)stepType.GetConstructor(new Type[] { paramType }).Invoke(new object[] { paramValue }); this.Steps.Add(new Step(step, stepInstance)); } else { throw new NotSupportedException($@"The step type ""{stepType}"" doesn't implement ""{typeof(IStep<>)}"" interface"); } } }
public static async Task Main(string[] args) { if (args.Count() < 1) { Console.WriteLine(@"Missing argument. Syntax: ""Workflow.ConsoleApp <workflow-definition-filename.json>"""); return; } string workflowFileName = args[0]; string workflowJson = File.ReadAllText(workflowFileName); Model.WorkflowDefinition workflowDefinition = JsonConvert.DeserializeObject <Model.WorkflowDefinition>(workflowJson); workflowDefinition.FileName = workflowFileName; //create and validate workflow Workflow.Framework.Workflow workflow = new Workflow.Framework.Workflow(workflowDefinition, Assembly.Load("Workflow.Extensions")); //execute workflow await workflow.ExecuteAsync(); }