1

我正在尝试从 PHP 迁移到 ASP.NET,并在此过程中尝试了解 MVC 的工作原理,但是我坚持使用 ControllerActionInvoker.InvokeActionMethodWithFilters,因为我不明白发生了什么。

我正在努力的片段如下:

protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
    ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
    Func<ActionExecutedContext> continuation = () =>
                                               new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
                                                                    (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));
    return thunk();
}

完整的源代码可以在以下 URL 中找到: https ://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ControllerActionInvoker.cs#L371

特别是,我不确定以下内容在做什么:

    Func<ActionExecutedContext> continuation = () =>
                                               new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

因为我以前从未见过包含以下内容的行:continuation = () =>

我似乎也无法在 Google 上找到答案,因为它不将 = () => 识别为搜索词。

我对以下具有相似语法的代码片段感到困惑:

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
                                                                    (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));

来自 PHP 背景,我以前没有见过这种语法,而且我在网上阅读的资源也没有真正让我明白。

基于以下 SO 问题: delegate keyword vs. lambda notation

如果我要重写以下...

    Func<ActionExecutedContext> continuation = () =>
                                               new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

会不会是这样...

    Func<ActionExecutedContext> continuation = delegate(new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */))
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

第二个片段也是如此......

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
                                                                    (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));

如果我没记错的话应该是...

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation, delegate(next, filter) {InvokeActionMethodFilter(filter, preContext, next)});

还是我仍然没有得到它?

4

1 回答 1

0

它是一个lambda 表达式,在这种特殊情况下,它只不过是匿名函数。

如果我没记错的话应该是...

错误的。它是具有两个参数的函数的委托,next并且filter将委托返回给另一个函数,该函数调用InvokeActionMethodFilter方法:

Func<ActionExecutedContext> thunk =
    filters.Reverse()
           .Aggregate(continuation,
                      delegate(Func<ActionExecutedContext> next, IActionFilter filter)
                      {
                          return delegate
                          {
                              return InvokeActionMethodFilter(filter, preContext, next);
                          };
                      });

此代码链接 IActionFilters 调用,直到其中一些产生结果。而在链的末端是你的行动方法。变量next要么是过滤器执行函数() => InvokeActionMethodFilter(filter, preContext, next),要么continuation是链的末尾。有关详细信息,请参阅InvokeActionMethodFilter实现。

于 2014-12-15T11:32:27.317 回答