读ASP.NET MVC5 框架揭秘有感

前言:

之前一直觉得这本书落伍了,现在都已经.NET Core 3.0时代了,.NET FrameX的时代已经过去了。但是回想一下程序的思路都是相同的,尤其是在我看了.NET core的部分源码之后惊为天人,原来程序是可以这样设计的。后来了解到老A用200行代码实现了一个Mini版的Core框架看了之后觉得讲的清晰,也随之发现这本书的作者就是老A。想着买一本来拜读奈何已经卖的绝版了,市场上都是二手书但是卖天价。觉得不值遂买了电子版的。这里不得不吐槽一下电子书,程序类的还是尽量看纸质书吧。翻页特别不方便。不仅仅是因为排版的问题。有时候我看到这章想要跳到前几章就要来回切换不如纸质书方便。磨磨蹭蹭终于把代码按照书本上敲出来运行成功了。其实书上有的代码一定要跟着写一下才会理解深刻。也因为是电子书的关系吧。关联着看特别不舒服。如果我写在程序里就可以用F12查看管理代码也很方便。

正文:

实现MiniMVC的原理就是在Modules里添加自定义Module。这里我添加的Module是UrlRoutingModule。该Module 重写了OnPostResolveRequestCache事件。OnPostResolveRequestCache事件是利用缓存对请求做出相应。他的后面就是PostMapRequestHandler,在这个事件里会对不同的HttpModule匹配不同的HttpHandler进行处理。所以我们要在这个事件之前处理。在OnPostResolveRequestCache事件里完成RouteData的构建以及HttpHandler的获取。并将HttpContenxt重新映射此HttpHandler。

在具体实现中,Global中的Application_Start事件中添加了对RouteTable的注册,因此能根据httpContext去获得RouteData.再根据RouteData和HttpContext去获得HttpHandler。其实这里取的HttpHandler是Route默认实现的是MvcHandler。接着在MvcHandler的ProcessRequest方法中通过工厂方式反射构造了一个Controller。再调用该Controller的Excute方法。在Excuete方法中调用ControllerActionInvoker的InvokeAction方法完成对该Controller的Action方法调用。在这期间利用ModelBinder的BindModel方法完成对action方法所需要的model构造。最后通过反射的方式完成对action的调用。这里值得一提的是。老A的博客上这里提供下载的代码是硬生生的反射。书上有反射转化为表达式的Compile调用。性能提高不少。这里反射只是生成一个ActionResult对象。最后执行ActionResult对象的ExecuteResult方法完成对HttpRepose的Output就算是走完了一个请求.

这里值得一提的是代码中不曾有的通过表达式反射的部分。我先把代码贴出来

 1 private static Func<object,object[],object> CreateExecutor(MethodInfo methodInfo)
 2         {
 3             ParameterExpression target = Expression.Parameter(typeof(object), "target");
 4             ParameterExpression arguments = Expression.Parameter(typeof(object[]), "arguments");
 5 
 6             List<Expression> parameters = new List<Expression>();
 7             ParameterInfo[] parameterInfos = methodInfo.GetParameters();
 8             for (int i = 0; i < parameterInfos.Length; i++)
 9             {
10                 ParameterInfo parameterInfo = parameterInfos[i];
11                 BinaryExpression getElementByIndex = Expression.ArrayIndex(arguments, Expression.Constant(i));
12                 UnaryExpression convertToParameterType = Expression.Convert(getElementByIndex, parameterInfo.ParameterType);
13                 parameters.Add(convertToParameterType);
14             }
15             UnaryExpression instanceCast = Expression.Convert(target, methodInfo.ReflectedType);
16             MethodCallExpression methodCall = Expression.Call(instanceCast, methodInfo, parameters);
17             UnaryExpression convertToObjectType = Expression.Convert(methodCall, typeof(object));
18             return Expression.Lambda<Func<object, object[], object>>(convertToObjectType, target, arguments).Compile();
19         }

在第三、四行定义了两个参数表达式。接着是获取目标方法的所需参数。在for循环中先是获取所需参数(第十行)。接着转化为arguments[i]的形式(第11行)。再着将arguments[i]强制转化为parameterInfo的类型(第12行)。前面都是讲方法所需要的参数转化成表达式,第15行则是将方法所运行的载体转化成了表达式。接着将instacneCast,methodInfo,parameters转化成了一个MethodCallExpression。最后将所有的对象拼接为一个lambda表达式并compile。值得一提的是。这样的做法效率非常高。具体可以参考https://blog.walterlv.com/post/create-delegate-to-improve-reflection-performance.html

另外。本文的参考http://www.cnblogs.com/artech/archive/2012/03/11/mvc-how-to-work-01.html

 

这是我第一次写博客。希望大家可以多多批评

转载于:https://www.cnblogs.com/dbdn/p/10870133.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值