예제 #1
0
        public async Task InvokerAsync()
        {
            var controllerType  = ActionContext.ActionDiscriptor.MethodInfo.DeclaringType;
            var serviceProvider = ActionContext.HttpContext.RequestServices;
            var controller      = (Controller)ActivatorUtilities.CreateInstance(serviceProvider, controllerType);

            controller.ActionContext = ActionContext;
            var executor = serviceProvider.GetRequiredService <IActionMethodExecutor>();

            var valueFactories     = serviceProvider.GetServices <IValueProviderFactory>();
            var valueProviders     = valueFactories.Select(item => item.CreateValueProvider(ActionContext)).ToArray();
            var valueProvider      = new CompositeValueProvider(valueProviders);
            var parameters         = ActionContext.ActionDiscriptor.MethodInfo.GetParameters();
            var arguments          = new object[parameters.Length];
            var modelBinderFactory = serviceProvider.GetRequiredService <IModelBinderFactory>();

            for (var index = 0; index < arguments.Length; index++)
            {
                var metadata      = ModelMetadata.Create(parameters[index]);
                var binder        = modelBinderFactory.CreateModelBinder(metadata);
                var binderContext = valueProvider.ContainsPrefix(metadata.ModelName)
                    ? new ModelBindingContext(ActionContext, metadata, valueProvider, metadata.ModelName)
                    : new ModelBindingContext(ActionContext, metadata, valueProvider, "");
                await binder.BindAsync(binderContext);

                arguments[index] = binderContext.Model;
            }

            var result = executor.Convert(controller, ActionContext, arguments);
            //var result = executor.Convert(controller, ActionContext, new object[0]);
            var converter    = serviceProvider.GetRequiredService <IActionResultConvertor>();
            var actionResult = converter.Convert(result, ActionContext);
            await actionResult.ExcuteResultAsync(ActionContext);
        }
        public async Task BindAsync(ModelBindingContext modelBindingContext)
        {
            var metaData = modelBindingContext.ModelMetadata;
            var model    = Activator.CreateInstance(metaData.ModelType);

            foreach (var property in metaData.ModelType.GetProperties().Where(p => p.SetMethod != null))
            {
                var propertyMetaData = ModelMetadata.Create(property);
                var binderFactory    = modelBindingContext.ActionContext.HttpContext.RequestServices.GetRequiredService <IModelBinderFactory>();
                var binder           = binderFactory.CreateModelBinder(propertyMetaData);
                var modelName        = string.IsNullOrWhiteSpace(modelBindingContext.ModelName)
                    ? property.Name
                    : $"{metaData.ModelName}.{property.Name}";
                var propertyContext = new ModelBindingContext(modelBindingContext.ActionContext, propertyMetaData, modelBindingContext.ValueProvider, modelName);
                await binder.BindAsync(propertyContext);

                if (propertyContext.IsModelSet)
                {
                    property.SetValue(model, propertyContext.Model);
                }
            }
            modelBindingContext.Bind(model);
        }