在理清路由的工作流程后,接下来需要考虑的,是MVC框架如何生成Controller以及它的生成时机。
根据以前ASP.NET MVC的经验,Controller应该是由一个ControllerFactory构建的。查看ASP.NET Core MVC的源码,果然是有一个DefaultControllerFactory类,并且不出意外的,它拥有一个CreateController方法。
public virtual object CreateController(ControllerContext context){ ???... ???var controller = _controllerActivator.Create(context); ???foreach (var propertyActivator in _propertyActivators) ???{ ???????propertyActivator.Activate(context, controller); ???} ???return controller;}
但细推其使用的场合,只出现在ControllerFactoryProvider的构造方法内部,且仅是用于判断所传入的controllerFactory类型是否是DefaultControllerFactory。
public ControllerFactoryProvider( ???IControllerActivatorProvider activatorProvider, ???IControllerFactory controllerFactory, ???IEnumerable<IControllerPropertyActivator> propertyActivators){ ???... ???_activatorProvider = activatorProvider; ???// Compat: Delegate to the IControllerFactory if it‘s not the default implementation. ???if (controllerFactory.GetType() != typeof(DefaultControllerFactory)) ???{ ???????_factoryCreateController = controllerFactory.CreateController; ???????_factoryReleaseController = controllerFactory.ReleaseController; ???} ???_propertyActivators = propertyActivators.ToArray();}
再看ControllerFactoryProvider内部的CreateControllerFactory方法。这更像是一个真正创建Controller的工厂方法。
public Func<ControllerContext, object> CreateControllerFactory(ControllerActionDescriptor descriptor){ ???... ???if (_factoryCreateController != null) ???{ ???????return _factoryCreateController; ???} ???var controllerActivator = _activatorProvider.CreateActivator(descriptor); ???var propertyActivators = GetPropertiesToActivate(descriptor); ???object CreateController(ControllerContext controllerContext) ???{ ???????var controller = controllerActivator(controllerContext); ???????for (var i = 0; i < propertyActivators.Length; i++) ???????{ ???????????var propertyActivator = propertyActivators[i]; ???????????propertyActivator(controllerContext, controller); ???????} ???????return controller; ???} ???return CreateController;}
创建方式分为两种,一种是使用自定义的工厂方法,另一种是通过ControllerActivatorProvider的CreateActivator方法。
public Func<ControllerContext, object> CreateActivator(ControllerActionDescriptor descriptor){ ???... ???var controllerType = descriptor.ControllerTypeInfo?.AsType(); ???... ???if (_controllerActivatorCreate != null) ???{ ???????return _controllerActivatorCreate; ???} ???var typeActivator = ActivatorUtilities.CreateFactory(controllerType, Type.EmptyTypes); ???return controllerContext => typeActivator(controllerContext.HttpContext.RequestServices, arguments: null);}
明白了如何创建Controller,下面开始调查创建Controller的时机。
ControllerFactoryProvider类的CreateControllerFactory方法是被ControllerActionInvokerCache类的GetCachedResult方法调用。
public (ControllerActionInvokerCacheEntry cacheEntry, IFilterMetadata[] filters) GetCachedResult(ControllerContext controllerContext){ ???var cache = CurrentCache; ???var actionDescriptor = controllerContext.ActionDescriptor; ???IFilterMetadata[] filters; ???if (!cache.Entries.TryGetValue(actionDescriptor, out var cacheEntry)) ???{ ???????var filterFactoryResult = FilterFactory.GetAllFilters(_filterProviders, controllerContext); ???????filters = filterFactoryResult.Filters; ???????var parameterDefaultValues = ParameterDefaultValues ???????????.GetParameterDefaultValues(actionDescriptor.MethodInfo); ???????var objectMethodExecutor = ObjectMethodExecutor.Create( ???????????actionDescriptor.MethodInfo, ???????????actionDescriptor.ControllerTypeInfo, ???????????parameterDefaultValues); ???????var controllerFactory = _controllerFactoryProvider.CreateControllerFactory(actionDescriptor); ???????var controllerReleaser = _controllerFactoryProvider.CreateControllerReleaser(actionDescriptor); ???????var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate( ???????????_parameterBinder, ???????????_modelBinderFactory, ???????????_modelMetadataProvider, ???????????actionDescriptor); ???????var actionMethodExecutor = ActionMethodExecutor.GetExecutor(objectMethodExecutor); ???????cacheEntry = new ControllerActionInvokerCacheEntry( ???????????filterFactoryResult.CacheableFilters, ????????????controllerFactory, ????????????controllerReleaser, ???????????propertyBinderFactory, ???????????objectMethodExecutor, ???????????actionMethodExecutor); ???????cacheEntry = cache.Entries.GetOrAdd(actionDescriptor, cacheEntry); ???} ???else ???{ ???????// Filter instances from statically defined filter descriptors + from filter providers ???????filters = FilterFactory.CreateUncachedFilters(_filterProviders, controllerContext, cacheEntry.CachedFilters); ???} ???return (cacheEntry, filters);}
其值作为ControllerActionInvokerCacheEntry对象的一部分被方法返回。
GetCachedResult方法的上层调用者是ControllerActionInvokerProvider类的OnProvidersExecuting方法。
public void OnProvidersExecuting(ActionInvokerProviderContext context){ ???... ???if (context.ActionContext.ActionDescriptor is ControllerActionDescriptor) ???{ ???????var controllerContext = new ControllerContext(context.ActionContext); ???????// PERF: These are rarely going to be changed, so let‘s go copy-on-write. ???????controllerContext.ValueProviderFactories = new CopyOnWriteList<IValueProviderFactory>(_valueProviderFactories); ???????controllerContext.ModelState.MaxAllowedErrors = _maxModelValidationErrors; ???????var cacheResult = _controllerActionInvokerCache.GetCachedResult(controllerContext); ???????var invoker = new ControllerActionInvoker( ???????????_logger, ???????????_diagnosticSource, ???????????controllerContext, ???????????cacheResult.cacheEntry, ???????????cacheResult.filters); ???????context.Result = invoker; ???}}
ControllerActionInvokerCacheEntry对象又被作为ControllerActionInvoker对象的一部分为ActionInvokerProviderContext的Result属性赋值。
再往上跟踪,到了ActionInvokerFactory类的CreateInvoker方法。
public IActionInvoker CreateInvoker(ActionContext actionContext){ ???var context = new ActionInvokerProviderContext(actionContext); ???foreach (var provider in _actionInvokerProviders) ???{ ???????provider.OnProvidersExecuting(context); ???} ???for (var i = _actionInvokerProviders.Length - 1; i >= 0; i--) ???{ ???????_actionInvokerProviders[i].OnProvidersExecuted(context); ???} ???return context.Result;}
而它的调用者便是MvcRouteHandler或者MvcAttributeRouteHandler。
public Task RouteAsync(RouteContext context){ ???... ???context.Handler = (c) => ???{ ???????var routeData = c.GetRouteData(); ???????var actionContext = new ActionContext(context.HttpContext, routeData, actionDescriptor); ???????if (_actionContextAccessor != null) ???????{ ???????????_actionContextAccessor.ActionContext = actionContext; ???????} ???????var invoker = _actionInvokerFactory.CreateInvoker(actionContext); ???????if (invoker == null) ???????{ ???????????throw new InvalidOperationException( ???????????????Resources.FormatActionInvokerFactory_CouldNotCreateInvoker( ???????????????????actionDescriptor.DisplayName)); ???????} ???????return invoker.InvokeAsync(); ???}; ???...}
到了这里创建Controller的工厂方法还没有被实际调用,此时Controller还是不存在的。所以还需要完成执行ControllerActionInvoker的InvokeAsync方法,或者更准确地说是其基类ResourceInvoker的InvokeAsync方法。
public virtual async Task InvokeAsync(){ ???try ???{ ???????... ???????using (_logger.ActionScope(_actionContext.ActionDescriptor)) ???????{ ???????????... ???????????try ???????????{ ???????????????await InvokeFilterPipelineAsync(); ???????????} ???????????... ???????} ???} ???...}
从InvokeFilterPipelineAsync方法开始,一系列的处理流程将依据不同状态逐步展开。
private async Task InvokeFilterPipelineAsync(){ ???var next = State.InvokeBegin; ???var scope = Scope.Invoker; ???var state = (object)null; ???var isCompleted = false; ???while (!isCompleted) ???{ ???????await Next(ref next, ref scope, ref state, ref isCompleted); ???}}
而到了State.ActionBegin这一步(ControllerActionInvoker类的Next方法),终于能找到Controller工厂方法被执行的场合。
private Task Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted){ ???switch (next) ???{ ???????case State.ActionBegin: ???????????{ ???????????????var controllerContext = _controllerContext; ???????????????_cursor.Reset(); ???????????????_instance = _cacheEntry.ControllerFactory(controllerContext); ???????????????_arguments = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); ???????????????var task = BindArgumentsAsync(); ???????????????if (task.Status != TaskStatus.RanToCompletion) ???????????????{ ???????????????????next = State.ActionNext; ???????????????????return task; ???????????????} ???????????????goto case State.ActionNext; ???????????} ???????... ???????} ???????????????}} ???????????
最后以一张流程图总结上面的探寻过程。
.NET Core开发日志——Controller
原文地址:https://www.cnblogs.com/kenwoo/p/9496297.html