您的位置:首页 > 编程语言 > ASP

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

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);



最后ResultFilter的调用和以上的分析是一样的,理解了这个就理解的ResultFilter的调用.

后记;

相关文章:

1.巧用Aggregate和委托构造递归链

转载请注明出处:/article/7081953.html

本文作者: 十一月的雨 http://www.cnblogs.com/RobbinHan
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: