首页 > 编程语言 >ASP.NET没有魔法——ASP.NET MVC Controller的实例化与执行

ASP.NET没有魔法——ASP.NET MVC Controller的实例化与执行

时间:2023-04-19 10:57:10浏览次数:49  
标签:ASP 创建 MvcHandler Controller MVC 类型 NET

原文: https://www.cnblogs.com/selimsong/p/7677108.html

上一章节中对路由的注册和匹配过程进行了介绍,知道了MVC的Http请求最终是交由MvcHandler处理的,而其处理过程就是对Controller的创建、执行和释放。
  本章将从以下几点进一步对上面提到的三个过程进行介绍:
  ● MvcHandler概述
  ● ControllerBuilder&ControllerFactory
  ● DefaultControllerFactory
  ● Controller&ControllerBase
  ● Controller的执行

 MvcHandler概述

  MvcHandler是MVC的核心组件,用于接收并处理来自客户的MVC请求,以下是MvcHandler类型的定义:

  

  MvcHandler实现了IHttpHandler和异步的IHttpAsyncHandler接口,这两个接口是用于处理Http请求的接口,其实这里所谓的“处理”就是根据用户请求的信息来生成一个响应信息返回到客户端。所以Mvc中也一样,通过Http请求的Head、Body等信息从中抓取需要的数据,然后将其传入Controller的Action中执行业务逻辑后,渲染一个Html模板返回至客户端显示。

  它的构造需要一个RequestContext对象。而RequestContext其实是HttpContextBase(包含了HTTP请求的所有信息)和RouteData的封装,这个对象是在UrlRoutingModule中创建的,然后通过MvcRouteHandler传到了MvcHandler中。

  以下是MvcHandler的处理概况图:

 

ControllerBuilder&ControllerFactory

  MvcHandler执行的一个步骤就是初始化,其中最重要的就是创建Controller,而Controller的创建离不开ControllerBuilder和ControllerFactory,那么它们到底起到什么作用?

  1. ControllerBuilder:用于获取和设置ControllerFactory,在没有设置过ControllerFactory的情况下默认获得DefaultControllerFactory。

  以下是ControllerBuilder的定义:

  

  2. ControllerFactory:它其实是一个IControllerFactory接口,专门用于创建和销毁Controller。MVC的默认实现是DefaultControllerFactory。

  

  综上所述,ControllerBuilder用于创建ControllerFactory,而ControllerFactory用于创建Controller,而ControllerFactory的默认实现是DefaultControllerFactory。

DefaultControllerFactory

  以下是DefaultControllerFactory的定义:

  

  它除了实现IControllerFactory的方法外还有两个名为GetControllerInstance、GetControllerType的受保护的虚方法,另外构造方法有一个类型为IControllerActivator的参数。前者很容易理解,在.Net中可以通过一个类型来创建一个实例,而可以通过类型名称在程序集中找到对应的类型。所以可以想到的是两个方法分别就是根据Controller的名称获取类型然后在通过类型创建实例的方法。而后者从名称看来是Controller的激活器,那它的作用是什么呢?是用来创建Controller实例的吗?

  以下是CreateController的代码,从代码中也证实了上面的猜测,Controller的创建是先根据Controller名称查找类型,然后通过类型创建Controller实例。

  

  1. Controller类型的查找:

    1). 命名空间的处理:路由中的命名空间、ControllerBuilder中的命名空间、无命名空间;三种命名空间从前到后依次以其值来作为命名空间匹配,直到找到对应Controller的类型。换句话说如果路由对象和Controller Builder都设置了命名空间,那么先根据路由对象的去查找,如果找不到再使用ControllerBuilder设置的命名空间,如果仍然没有就不使用命名空间来进行匹配。

    2). Controller类型缓存数据处理:为了提高MVC的性能,在通过缓存的形式在第一次查找Controller类型的时候遍历所有依赖程序集中的IController类型生成一个名称为“MVC-ControllerTypeCache.xml”缓存文件(由ControllerTypeCache类型完成),以下是缓存文件格式:

    

    注:该缓存路径一般在systemroot\Microsoft .NET\Framework\versionNumber\Temporary ASP.NET Files\{app name}\..\..\UserCache或systemroot\Microsoft .NET\Framework\versionNumber\Temporary ASP.NET Files\root\..\..\UserCache目录下,但是可能由于Web宿主不同或环境配置不同而不同,但是可以在代码中通过HttpRuntime.CodegenDir属性找到。另外还有一个缓存文件是对Area注册的缓存,名称为MVC-AreaRegistrationTypeCache.xml。

    3). 类型的匹配:Controller的类型匹配相对简单,它使用{NameSpace}.{ControllerName}的形式在上面文件的数据结构中匹配。

  2. Controller的创建:

    1). 判断Controller类型是否是继承于IController。

    2). 通过ControllerActivator创建Controller实例。

  3. 关于ControllerActivator:用于Controller的创建,在MVC中有一个DefaultControllerActivator存在于DefaultControllerFactory中,它用于通过.Net中的Activator对象或依赖解析器创建Controller实例。

    

Controller&ControllerBase

  在开发中MVC控制器的时候,一般以Controller类型作为基类,通过继承的方式来完成。这样可以轻松的获得Controller基类提供的功能。而Controller其实是继承至ControllerBase抽象类,ControllerBase中提供了MVC中最核心的Execute方法和ExecuteCore抽象方法以及必要的一些属性如TempDataDictionary以及ViewDataDictionary等,使用典型的模板模式规定了Controller类型的框架。

  1. ControllerBase:定义了Controller的核心框架

  

  2. Controller:实现了ASP.NET MVC中控制器的执行逻辑,以及附加功能,如验证、异常处理、事件处理(Action执行事件、验证事件等)、跳转、多种返回类型(包括但不限于MVC页面、Json数据、文件、普通内容)等。

  注:由于Controller定义代码太多,所以不在放出,大家可以在VS中查看。

Controller的执行

  上面提到过ControllerBase是整个Controller类结构的模板,所以在ASP.NET MVC调用Controller执行时实际上是调用的ControllerBase类型的Execute方法,而该方法内部实际上调用的是子类的ExecuteCore方法,以下是Controller类型的ExecuteCore:

  

  从代码可以看出Controller的执行“很”简单,只有四步:加载临时数据、获取Action、执行Action、保存临时数据。

  注:本章不再对Action的执行进行介绍,因为Action的执行包含了很多内容,比如过滤器的执行、模型的绑定等,所以这些内容会在后续讲解。

小结

  本章以MvcHandler的执行为入口,以MVC控制器的创建、执行为流程,介绍了其相关的重要对象和执行逻辑。更多内容请关注后续文章。

 

本文链接:http://www.cnblogs.com/selimsong/p/7677108.html

ASP.NET没有魔法——目录

作者:7m鱼
出处:http://www.cnblogs.com/selimsong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

标签:ASP,创建,MvcHandler,Controller,MVC,类型,NET
From: https://www.cnblogs.com/bruce1992/p/17332541.html

相关文章

  • ASP.NET Core - 缓存之分布式缓存
    分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护。分布式缓存可以提高ASP.NETCore应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时。与其他将缓存数据存储在单个应用服务器上的缓存方案相比,分布式缓存具有多个优势。当分发......
  • .NET周报 【4月第3期 2023-04-15】
    国内文章SemanticKernel入门系列:......
  • CS144 计算机网络 Lab0:Networking Warmup
    前言本科期间修读了《计算机网络》课程,但是课上布置的作业比较简单,只是分析了一下Wireshark抓包的结构,没有动手实现过协议。所以最近在哔哩大学在线学习了斯坦福大学的CS144计算机网课程,这门课搭配了几个Lab,要求动手实现一个TCP协议,而不是简单地调用系统为我们提供好的So......
  • 第一章 使用MASA Stack+.Net 从零开始搭建IoT平台 环境准备
    @目录前言架构图一、设备接入二、处理设备遥测数据三、设备控制四、管理后台五、数据存储六、规则引擎环境准备1、安装EMQX2、创建解决方案3、安装Dapr开发环境前言本系列文章以IoT开发小白的角度,从零开始使用.Net为主要技术搭建一个简单的IoT平台,由于是入门系列,所有代码以围绕I......
  • 第二章 使用MASA Stack+.Net 从零开始搭建IoT平台 设备生命周期管理-设备注册.
    设备生命周期管理-设备注册@目录设备生命周期管理-设备注册前言一、设备注册流程二、MQTT注册1.在EMQX中添加认证方式2.创建ApiKey3.调用接口创建用户三、测试设备连接四、编写代码总结前言我们不希望任何设备都可以接入我们的IoT平台,所以一个设备正常的接入流程是这样的,1、......
  • 关于PythonNet与TensorFlow的调试技巧
    1.使用TensorFlow2.x版本训练的模型,在导入时容易报错,不要跨版本训练或者调用模型。报错内容通常定位到restore方法。2.PythonNet调用py文件报错时,右键该文件执行后报错内容会一闪而过,可以右键使用Python编译器(Idel)打开,错误会详细显示,且内容与编辑器一样。3.TensorFlow1.9最......
  • Shifu物联网开发框架成为MicroK8s官方认证的Kubernetes插件
    Shifu物联网开发框架已经成为Kubernetes生态下MicroK8s官方认证的插件,这将极大地简化基于K8s的物联网应用程序的开发,帮助企业高效搭建获得安全、可控的生产级物联中台。MicroK8s是一个轻量级的CNCF认证的Kubernetes发行版,适用于云、工作站、边缘和物联网设备。Shifu用作K......
  • 分享一个很好用的代理转发工具:rinetd
    rinetd介绍:安装与使用:https://zhuanlan.zhihu.com/p/530875131注意事项:1、如果发现配置中的端口在进程中没找到,那就是配置填写错误导致的,笔者就遇到过,端口写个了66666,结果就翻车了,切记按照规则来操作使用场景1、需要测试网络中断的场景,模拟网络异常2、测试负载均衡,等等......
  • 2023 ASP.NET Core 开发者路线图
    链接ASP.NETCoreDeveloperRoadmap......
  • 面向接口编程实践之aspnetcoreapi的抽象
    最为一名越过菜鸟之后的开发,需要做接口开发。下面做一个纯粹的接口编程的实例demo,仅仅是一个webapi接口的抽象。下面是代码接口,AbsEFWork是webapi,BaseEntityFramework是一个接口库。先介绍一下webapi的实现,代码是从底层往上层写的,阅读代码的习惯应该是自上向下。publiccla......