从实现上说,ControllerActionInvoker其实是ResourceInvoker的子类。其InvokeAsync()方法的主要流程就是调用InvokeFilterPipelineAsync()。
ResourceInvoker
ResourceInvoker中的Resource含义和Resource filters中的含义相同。但是这里的ResourceInvoker会负责调用整个Filter管道,主要包括Authorization Filters(2.x)、Exception Filters、Model Binding、Action Filters、及Result Filters的全部过程:
public virtual async Task InvokeAsync()
{
try{
//.. diagnose;
using (_logger.ActionScope(_actionContext.ActionDescriptor)){
// ... log
try {
await InvokeFilterPipelineAsync();
} finally{
ReleaseResources();
// ... log
}
}
} finally {
//.. diagnose;
}
}
显然,这里的InvokeFilterPipelineAsync()是整个方法的核心,该方法会不停地尝试调用自身的一个Next方法,直至结束:
private async Task InvokeFilterPipelineAsync()
{
var next = State.InvokeBegin;
// The `scope` tells the `Next` method who the caller is, and what kind of state to initialize to
// communicate a result. The outermost scope is `Scope.Invoker` and doesn't require any type
// of context or result other than throwing.
var scope = Scope.Invoker;
// The `state` is used for internal state handling during transitions between states. In practice this
// means storing a filter instance in `state` and then retrieving it in the next state.
var state = (object)null;
// `isCompleted` will be set to true when we've reached a terminal state.
var isCompleted = false;
while (!isCompleted)
{
await Next(ref next, ref scope, ref state, ref isCompleted);
}
}
protected abstract Task InvokeInnerFilterAsync();
而Next()方法负责依次调用管道内的Filter。对于具体的Action Filters 及Action本身的调用,则交由抽象方法InvokeInnerFilterAsync()定义,延迟到子类中实现。
ASP.NET Core中内置的ResourceInvoker实现有ControllerActionInvoker和PageActionInvoker,分别负责对MVC中Action进行调用和对RazorPage的handler进行调用。
ControllerActionInvoker
ControllerActionInvoker对父类抽象方法InvokeInnerFilterAsync()的实现是也是通过状态机实现,如果是同步调用,大致的流程是:
filter.OnActionExecuting(),InvokeActionMethodAsync(),filter.OnActionExecuted()
事实上,ASP.NET Core MVC中内置的Controller抽象类自身也是一个IActionFilter:
public abstract class Controller : ControllerBase, IActionFilter, IAsyncActionFilter, IDisposable
{
...
[NonAction] public virtual void OnActionExecuting(ActionExecutingContext context) { }
[NonAction] public virtual void OnActionExecuted(ActionExecutedContext context){ }
[NonAction] public virtual Task OnActionExecutionAsync( ActionExecutingContext context, ActionExecutionDelegate next)
{
if (context == null) { /* throw */; }
if (next == null) { /* throw */; }
OnActionExecuting(context);
if (context.Result == null)
{
var task = next();
if (!task.IsCompletedSuccessfully)
{
return Awaited(this, task);
}
OnActionExecuted(task.Result);
}
return Task.CompletedTask;
static async Task Awaited(Controller controller, Task<ActionExecutedContext> task){ controller.OnActionExecuted(await task); }
}
...
}
可以看到,这里Controller::OnActionExecutionAsync(ctx,next)方法会按如下顺序依次调用:
OnActionExecuting(executingContext)方法next()委托,也就是Action方法本身OnActionExecuted(executedContext)方法和普通的ActionFilter行为一致。










