public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
if (_request != null)
{
// if user has registered a controller factory which produces the same controller instance, we should throw here
throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, typeof(ApiController).Name, typeof(IHttpControllerActivator).Name);
}
Initialize(controllerContext);
// We can't be reused, and we know we're disposable, so make sure we go away when
// the request has been completed.
if (_request != null)
{
_request.RegisterForDispose(this);
}
HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;
ServicesContainer controllerServices = controllerDescriptor.Configuration.Services;
HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);
HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor);
IEnumerable<FilterInfo> filters = actionDescriptor.GetFilterPipeline();
FilterGrouping filterGrouping = new FilterGrouping(filters);
IEnumerable<IActionFilter> actionFilters = filterGrouping.ActionFilters;
IEnumerable<IAuthorizationFilter> authorizationFilters = filterGrouping.AuthorizationFilters;
IEnumerable<IExceptionFilter> exceptionFilters = filterGrouping.ExceptionFilters;
// Func<Task<HttpResponseMessage>>
Task<HttpResponseMessage> result = InvokeActionWithAuthorizationFilters(actionContext, cancellationToken, authorizationFilters, () =>
{
HttpActionBinding actionBinding = actionDescriptor.ActionBinding;
Task bindTask = actionBinding.ExecuteBindingAsync(actionContext, cancellationToken);
return bindTask.Then<HttpResponseMessage>(() =>
{
_modelState = actionContext.ModelState;
Func<Task<HttpResponseMessage>> invokeFunc = InvokeActionWithActionFilters(actionContext, cancellationToken, actionFilters, () =>
{
return controllerServices.GetActionInvoker().InvokeActionAsync(actionContext, cancellationToken);
});
return invokeFunc();
});
})();
result = InvokeActionWithExceptionFilters(result, actionContext, cancellationToken, exceptionFilters);
return result;
}
首先调用Initialize方法初始化ControllerContext、_request、_configuration,紧接着就创建一个HttpActionDescriptor
HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);
在DefaultServices中有这么一句SetSingle<IHttpActionSelector>(new ApiControllerActionSelector());,所以我们就知道controllerServices.GetActionSelector()返回的是一个ApiControllerActionSelector实例。其中ApiControllerActionSelector的SelectAction实现也比较简单:
public virtual HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
ActionSelectorCacheItem internalSelector = GetInternalSelector(controllerContext.ControllerDescriptor);
return internalSelector.SelectAction(controllerContext);
}
我们首先来看看GetInternalSelector方法实现:、
private ActionSelectorCacheItem GetInternalSelector(HttpControllerDescriptor controllerDescriptor)
{
// First check in the local fast cache and if not a match then look in the broader
// HttpControllerDescriptor.Properties cache
if (_fastCache == null)
{
ActionSelectorCacheItem selector = new ActionSelectorCacheItem(controllerDescriptor);
Interlocked.CompareExchange(ref _fastCache, selector, null);
return selector;
}
else if (_fastCache.HttpControllerDescriptor == controllerDescriptor)