Asp.Net MVC5代码的筛选器(ActionFilter)执行递归链表分析

我们用筛选器控制Action运行前后需要处理的事情

public abstract class ActionFilterTestcs:FilterAttribute,IActionFilter

{

public void OnActionExecuted(ActionExecutedContext filterContext)

{ }

public void OnActionExecuting(ActionExecutingContext filterContext)

{ }

}


抽象一个ActionFilterTestcs

在Controller中比如HomeController中继承此抽象类

public class FooAttribute:ActionFilterTestcs

{

int a = 1;

}

在Action Index上面用上这两个筛选类如下:

[Bar]

[Foo]

public ActionResult Index()

{ return View();}


Filter 执行过程从 BeginInvokeActionMethodWithFilters开始

protected internal virtual IAsyncResult BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state)

{

Func<ActionExecutedContext> endContinuation = null;

BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState)

{

ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);

AsyncResult innerAsyncResult = null;

Func<Func<ActionExecutedContext>> beginContinuation = () => {

innerAsyncResult = BeginInvokeActionMethod(controllerContext, actionDescriptor, parameters, asyncCallback, asyncState);

return () =>

new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)

{

Result = EndInvokeActionMethod(innerAsyncResult)

};

}; // need to reverse the filter list because the continuations are built up backward

Func<Func<ActionExecutedContext>> thunk = filters.Reverse().Aggregate(beginContinuation,

(next, filter) => () => InvokeActionMethodFilterAsynchronously(filter, preContext, next));

endContinuation = thunk();

if (innerAsyncResult != null)

{ // we're just waiting for the inner result to complete

return innerAsyncResult;

}

else

{ // something was short-circuited and the action was not called, so this was a synchronous operation

SimpleAsyncResult newAsyncResult = new SimpleAsyncResult(asyncState);

newAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback);

return newAsyncResult;

}

};

EndInvokeDelegate<ActionExecutedContext> endDelegate = delegate(IAsyncResult asyncResult)

{

return endContinuation();

};

return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodWithFiltersTag);

}


通过 Aggregate构建了一个Action筛选器(IList<IActionFilter>)递归链表endContinuation = thunk();是这个链表的开始执行地方。

具体过程 Filter1,beginContinuation 返回结果为Aggregate累加。MVC5的ActionFilter链表递归结构跟MVC3,4 有一定的区别,前者BeginInvokeActionMethodWithFilters返回的是Func<Func<ActionExecutedContext>>,后者直接Func<ActionExecutedContext>


而执行过程,OnActionExecuted则是延缓了执行,从Func<Func<ActionExecutedContext>>到 Func<ActionExecutedContext>他通过了递归经过了一层剥离方法然后再执行OnActionExecuted执行过程为 :


Filter1.OnActionExecuting-》Filter2.OnActionExecuting-》-》Filter3.OnActionExecuting-》BeginInvokeActionMethod-》EndInvokeActionMethod-》Filter1.OnActionExecuted-》Filter2.OnActionExecuted-》Filter2.OnActionExecuted



MVC3,4执行过程为:Filter1.OnActionExecuting-》Filter2.OnActionExecuting-》-》Filter3.OnActionExecuting-》InvokeActionMethodFilter-》Filter3.OnActionExecuted-》Filter2.OnActionExecuted-》Filter1.OnActionExecuted

猜你喜欢

转载自blog.csdn.net/tangyanzhi1111/article/details/78368205