Asp.net MVC源码分析--Action Filter的链式调用
2011-12-01 10:11
661 查看
上一篇中我们介绍了asp.net MVC 的Filter的种类,以及调用的时点.今天我们来看一下ActionFilter/ResultFilter 调用的细节以及源码中令人叫绝的代码实现.首先我们看到在Contoller这个类中已经实现了IActionFilter/IResultFilter,并且它们的接口实现是调用两个虚函数来实现的,这就为我们提供了便利,可以在我们的Controller中重写这些虚函数来截获并实现我们自己的逻辑.
Controller.cs
View Code
我们看到Aggregate 第一个参数是初始值同时也决定了Aggregate 方法的返回类型, 第二个参数是一个委托,委托的第一个参数是上一次调用的返回,这里返回的类型也是一个委托.
---------------------------------------------------------------------------------------------
这时我们再看我们的InvokeActionMethodWithFilters 方法中 thunk 变量的声明:
第一个参数是continuation,它的类型是Func<ActionExecutedContext>,这就决定了我们Aggregate 方法的返回类型也是Func<ActionExecutedContext>, 再看第二个参数也是一个委托(注意这里这个方法也没有调用哦.)它的实现是调用InvokeActionMethodFilter方法. 这个委托会做为第三次迭代(如果有的话)Next参数.
所以最后在InvokeActionMethodFilter 方法的Next参数第一次是continuation变量,第二次是() => InvokeActionMethodFilter(filter, preContext, next));
.如果有第三次或第N次(有三个或N个Filter的情况)会同样第二次的操作, 最后返回给thunk变量的是最后一次生成的调用委托.
---------------------------------------------------------------------------------------------
哎这里好饶哦,对不起,我实在找不到其它词汇了.只能靠最后的一张图来帮助大家理解了.
声明时的伪代码:
var fun1 = (next, filter) => () => InvokeActionMethodFilter(filter, preContext, continuation);
var fun2 = (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun1)
var fun3 = (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun2)
最终thunk = fun3;
当thunk()调用的时候它的执行顺序是这样的.
调用时的伪代码:
invoke (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun3)
invoke (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun2)
invoke (next, filter) => () => InvokeActionMethodFilter(filter, preContext, continuation);
![](http://pic002.cnblogs.com/images/2011/69924/2011113016415683.gif)
最后ResultFilter的调用和以上的分析是一样的,理解了这个就理解的ResultFilter的调用.
后记;
相关文章:
1.巧用Aggregate和委托构造递归链
转载请注明出处:/article/7081953.html
本文作者: 十一月的雨 http://www.cnblogs.com/RobbinHan
Controller.cs
View Code
public static TAccumulate Aggregate<TSource, TAccumulate>( this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func ) //demo int[] ints = { 4, 8, 8, 3, 9, 0, 7, 8, 2 }; // Count the even numbers in the array, using a seed value of 0. int numEven = ints.Aggregate(0, (total, next) => next % 2 == 0 ? total + 1 : total); Console.WriteLine("The number of even integers is: {0}", numEven); // This code produces the following output: // // The number of even integers is: 6
我们看到Aggregate 第一个参数是初始值同时也决定了Aggregate 方法的返回类型, 第二个参数是一个委托,委托的第一个参数是上一次调用的返回,这里返回的类型也是一个委托.
---------------------------------------------------------------------------------------------
这时我们再看我们的InvokeActionMethodWithFilters 方法中 thunk 变量的声明:
第一个参数是continuation,它的类型是Func<ActionExecutedContext>,这就决定了我们Aggregate 方法的返回类型也是Func<ActionExecutedContext>, 再看第二个参数也是一个委托(注意这里这个方法也没有调用哦.)它的实现是调用InvokeActionMethodFilter方法. 这个委托会做为第三次迭代(如果有的话)Next参数.
所以最后在InvokeActionMethodFilter 方法的Next参数第一次是continuation变量,第二次是() => InvokeActionMethodFilter(filter, preContext, next));
.如果有第三次或第N次(有三个或N个Filter的情况)会同样第二次的操作, 最后返回给thunk变量的是最后一次生成的调用委托.
---------------------------------------------------------------------------------------------
哎这里好饶哦,对不起,我实在找不到其它词汇了.只能靠最后的一张图来帮助大家理解了.
声明时的伪代码:
var fun1 = (next, filter) => () => InvokeActionMethodFilter(filter, preContext, continuation);
var fun2 = (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun1)
var fun3 = (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun2)
最终thunk = fun3;
当thunk()调用的时候它的执行顺序是这样的.
调用时的伪代码:
invoke (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun3)
invoke (next, filter) => () => InvokeActionMethodFilter(filter, preContext, fun2)
invoke (next, filter) => () => InvokeActionMethodFilter(filter, preContext, continuation);
![](http://pic002.cnblogs.com/images/2011/69924/2011113016415683.gif)
最后ResultFilter的调用和以上的分析是一样的,理解了这个就理解的ResultFilter的调用.
后记;
相关文章:
1.巧用Aggregate和委托构造递归链
转载请注明出处:/article/7081953.html
本文作者: 十一月的雨 http://www.cnblogs.com/RobbinHan
相关文章推荐
- Asp.net MVC源码分析--Filter种类以及调用优先级
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
- asp.net mvc源码分析-DefaultModelBinder 集合绑定
- asp.net mvc源码分析-Controllerl篇 TempData数据存储
- asp.net mvc源码分析-ActionResult篇 FindView
- asp.net mvc源码分析-ActionResult篇 RazorView.RenderView
- asp.net mvc源码分析-AsyncController
- ASP_NET_MVC3_请求处理流程(2) MVC源码分析
- ASP.NET WebForm / MVC 源码分析
- Asp.net MVC源码分析--Model Validation(Server端)实现(2)
- Asp.net MVC源码分析--Model Validation(Client端)实现(1)
- asp.net mvc源码分析-路由篇 如何找到 IHttpHandler
- Asp.net MVC源码分析--Model Validation(Client端)实现(2)
- asp.net mvc源码分析-Action篇 Filter
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
- asp.net mvc源码分析-Route的GetRouteData
- ASP.NET WebForm / MVC 源码分析
- ASP.NET MVC 源码分析(一)
- asp.net mvc源码分析-Controllerl篇 TempData数据存储