void IInitializeWorkflowManager.Initialize(WorkflowInfo input) { if (WorkflowNotContainsWithoutParametersConstructor(input)) { throw new Exception("У типа задающего ворклфоу должен быть безпараметрический конструктор"); } var services = input.WorkflowName.GetNestedTypes().Select(_serviceProvider.GetService).ToList(); var chainMethodParameter = services.Select(x => new { method = x.GetType().GetMethod("Handle"), parameter = x.GetType().GetParametersByMethodName("Handle").FirstOrDefault() }) .Where(x => x.parameter != default) .ToList(); var parameterInfosList = chainMethodParameter.ToList(); ChainTypes = chainMethodParameter.SkipLast(1) .Aggregate(new[] { typeof(TIn) }.AsEnumerable(), (a, c) => { var currentHandlerInChain = parameterInfosList.First(x => x.parameter == a.Last()); return(a.Concat(currentHandlerInChain.method.GetGenericTypesReturnValue())); }) .Concat(new[] { typeof(TOut) }) .ToList(); foreach (var service in services) { var voidHandler = _voidHandlersFactory.Create((dynamic)service); if (voidHandler != null) { _voidHandlersExecutor.AddHandler(voidHandler); continue; } var rollBackHandler = _rollBackHandlerFactory.Create((dynamic)service); if (rollBackHandler != null) { _rollBackHandlersExecutor.AddHandler(rollBackHandler); } var resultHandler = _resultHandlersFactory.Create((dynamic)service); if (resultHandler != null) { _resultHandlersExecutor.AddHandler(resultHandler); } } }
public async Task BindModelAsync(ModelBindingContext bindingContext) { var actionParameters = bindingContext?.ActionContext?.ActionDescriptor?.Parameters; if (actionParameters.Count != 2) { throw new Exception("должно быть только два аргумента, один - тип вокфлоу, второй - инпут"); } Type ouputGenericType = null; var actionReturnType = ((ControllerActionDescriptor)bindingContext.ActionContext.ActionDescriptor) .MethodInfo.ReturnType; if (!actionReturnType.IsGenericType) { throw new Exception( "Используйте action'ы, которые возвращают ActionResult<T> или Task<ActionResult<T>>"); } var genericType = actionReturnType.GetGenericArguments().First(); if (actionReturnType.GetGenericTypeDefinition() == typeof(Task <>)) { if (genericType.GetGenericTypeDefinition() == typeof(ActionResult <>)) { ouputGenericType = genericType.GetGenericArguments().First(); } } else if (actionReturnType.GetGenericTypeDefinition() == typeof(ActionResult <>)) { ouputGenericType = genericType; } var workFlowType = ((ControllerParameterDescriptor)actionParameters .First(x => x.Name == bindingContext.FieldName)) .ParameterInfo .GetCustomAttribute <WorkFlow>() .WorkflowType; var dtoParameter = actionParameters.FirstOrDefault(x => x.Name != bindingContext.FieldName); if (dtoParameter == null) { throw new Exception(); } var dtoType = dtoParameter.ParameterType; var workflowManagerType = typeof(WorkflowManager <,>).MakeGenericType(dtoType, ouputGenericType); var workflowManager = (IInitializeWorkflowManager)bindingContext.HttpContext.RequestServices.GetService(workflowManagerType); workflowManager = (IInitializeWorkflowManager)ActivatorUtilities.CreateInstance( bindingContext.HttpContext.RequestServices, workflowManagerType, bindingContext.HttpContext.RequestServices); var workflowInfo = new WorkflowInfo { WorkflowName = workFlowType }; workflowManager.Initialize(workflowInfo); bindingContext.Model = workflowManager; bindingContext.Result = ModelBindingResult.Success(workflowManager); }
private static bool WorkflowNotContainsWithoutParametersConstructor(WorkflowInfo input) { return(input.WorkflowName.GetConstructors().All(x => x.GetParameters().Length != 0)); }