ASP.NET WebAPI 09 Controller的激活
2015-11-04 22:10
543 查看
在Controller之前我们先回顾一下HttpMessageHandler通道。
在这个图中我留一个HttpContollerDispatcher没有说明。因为这个类也是继承自HttpMessageHandler,但由于HttpRoutingDispatcher已经不继承DelegatingHandler,所以就没有把HttpControllerDisPatcher作为HttpMessageHandler通道的最后一个节点。
HttpControllerDispather的主要功能就是根据请求路径筛选出Contoller,并激活运行。
IHttpController只有一个ExecuteAsync方法,从方法的返回值。
HttpControllerDispatcher的SendAsync方法可以分成4个步骤:
获取HttpControllerDescriptor
创建HttpController
获取Controller上下文(HttpControllerContext)
执行HttpController的ExecuteAsync方法
整个获取HttpControllerDescriptor可以看成是根据路由变量controller的值在程序集中查找HttpControllerDescriptor。
WebAPI提供了查找的"标准化组件":HttpControllerSelector<IHttpControllerSelector,DefalutHttpControllerSelector>。
GetControllerMapping返回所有的HttpControllerDescriptor, SelectController按ControllerName返回ControllerType。
当然出于效率的考虑,WebAPI不会每次都去程序集中去查找。也是会做相应的缓存。对于加载缓存由两个"标准化组件"完成:IAssembliesResolver,IHttpControllerTypeResolver
IAssembliesResolver用于加载程序集。ASP.NET WebAPI注册是WebHostAssembliesResolver ,它定义在System.Web.Http.WebHost.dll中。它几乎返回运行过程中所有的程序集。
IHttpControllerTypeResolver用于从IAssembliesResolver获取到的程序集中筛选出所有的HttpController。WebAPI对它的默认实现是DefaultHttpControllerTypeResolver。筛选HttpController要满足如下条件:
直接或间接实现IHttpController的类
该类是公开的,非抽象的
该类的类名应该是以Controller结束
HttpControllerActivator是作为"标准化组件"注册在ServicesContainer中的.WebAPI的默认实现是DefaultHttpControllerActivator。
在DefaultHttpControllerActivator中最优先使用的并不是反射,而是采用的DependencyResolver方式进行创建。只有当DependencyResolver返回空是才采用反射方式创建HttpController,上一篇我也提到过HttpConfiguration的DependencyResolver默认是EmptyResolver,所以实际上WebAPI默认采用反射的方式创建HttpController。
当然我们可以自己去实现DependencyResolver。在Demo中我用Unity自大做了一个简单的UnityDependencyResolver。
在ApiController中有一Initialize方法,该方法就是用于设置ControllerContext并标识ApiControlle已完成初始化(当ApiController未标识完成时会抛出InvalidOperationException异常)。所以我们在重写该方法时一定不要漏掉base.Initialize。
整个Contoller的激活大概如下流程:
在这个图中我留一个HttpContollerDispatcher没有说明。因为这个类也是继承自HttpMessageHandler,但由于HttpRoutingDispatcher已经不继承DelegatingHandler,所以就没有把HttpControllerDisPatcher作为HttpMessageHandler通道的最后一个节点。
HttpControllerDispather的主要功能就是根据请求路径筛选出Contoller,并激活运行。
HttpController
在程序中默认创建的Controller都继承自抽象类ApiController,但在WebAPI只要Controller实现接口IHttpController即可。public interface IHttpController { Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken); }
IHttpController只有一个ExecuteAsync方法,从方法的返回值。
HttpControllerDispatcher的SendAsync方法可以分成4个步骤:
获取HttpControllerDescriptor
创建HttpController
获取Controller上下文(HttpControllerContext)
执行HttpController的ExecuteAsync方法
获取HttpControllerDescriptor
HttpControllerDescriptor封装了某个HttpController的元数据(ControllerName,ControllerType)。ControllerType是HttpController对应的类型,因为有了这些信息,所以HttpControllerDescriptor就有了创建HttpController的能力public class HttpControllerDescriptor { public HttpControllerDescriptor(); public HttpControllerDescriptor(HttpConfiguration configuration, string controllerName, Type controllerType); public HttpConfiguration Configuration { get; set; } public string ControllerName { get; set; } public Type ControllerType { get; set; } }
整个获取HttpControllerDescriptor可以看成是根据路由变量controller的值在程序集中查找HttpControllerDescriptor。
WebAPI提供了查找的"标准化组件":HttpControllerSelector<IHttpControllerSelector,DefalutHttpControllerSelector>。
public interface IHttpControllerSelector { IDictionary<string, HttpControllerDescriptor> GetControllerMapping(); HttpControllerDescriptor SelectController(HttpRequestMessage request); }
GetControllerMapping返回所有的HttpControllerDescriptor, SelectController按ControllerName返回ControllerType。
当然出于效率的考虑,WebAPI不会每次都去程序集中去查找。也是会做相应的缓存。对于加载缓存由两个"标准化组件"完成:IAssembliesResolver,IHttpControllerTypeResolver
IAssembliesResolver用于加载程序集。ASP.NET WebAPI注册是WebHostAssembliesResolver ,它定义在System.Web.Http.WebHost.dll中。它几乎返回运行过程中所有的程序集。
IHttpControllerTypeResolver用于从IAssembliesResolver获取到的程序集中筛选出所有的HttpController。WebAPI对它的默认实现是DefaultHttpControllerTypeResolver。筛选HttpController要满足如下条件:
直接或间接实现IHttpController的类
该类是公开的,非抽象的
该类的类名应该是以Controller结束
创建Controller
在得到HttpControllerDescriptor之后,HttpControllerDescriptor自身就有CreateController方法去创建Controller,但具体的工作HttpControllerDescriptor交给了HttpControllerActivator完成。public interface IHttpControllerActivator { IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType); }
HttpControllerActivator是作为"标准化组件"注册在ServicesContainer中的.WebAPI的默认实现是DefaultHttpControllerActivator。
在DefaultHttpControllerActivator中最优先使用的并不是反射,而是采用的DependencyResolver方式进行创建。只有当DependencyResolver返回空是才采用反射方式创建HttpController,上一篇我也提到过HttpConfiguration的DependencyResolver默认是EmptyResolver,所以实际上WebAPI默认采用反射的方式创建HttpController。
当然我们可以自己去实现DependencyResolver。在Demo中我用Unity自大做了一个简单的UnityDependencyResolver。
Controller上下文
Controller上下文对应的类的是HttpControllerContext,ApiController的ControllerContext就是HttpControllerContext对象。 ControllerContext包含了请求中的各种信息。激活Controller最后一步就是根据请求信息生成ControllerContext并赋值给ApiController.ControllerContext。public class HttpControllerContext { public HttpControllerContext(); public HttpControllerContext(HttpConfiguration configuration, IHttpRouteData routeData, HttpRequestMessage request); public HttpControllerContext(HttpRequestContext requestContext, HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, IHttpController controller); public HttpConfiguration Configuration { get; set; } public IHttpController Controller { get; set; } public HttpControllerDescriptor ControllerDescriptor { get; set; } public HttpRequestMessage Request { get; set; } public HttpRequestContext RequestContext { get; set; } public IHttpRouteData RouteData { get; set; } }
在ApiController中有一Initialize方法,该方法就是用于设置ControllerContext并标识ApiControlle已完成初始化(当ApiController未标识完成时会抛出InvalidOperationException异常)。所以我们在重写该方法时一定不要漏掉base.Initialize。
protected virtual void Initialize(HttpControllerContext controllerContext)
整个Contoller的激活大概如下流程:
源码
Github: https://github.com/BarlowDu/WebAPI (API_9)相关文章推荐
- ASP.NET中验证控件的使用
- JSP GridView --使用自定义标签实现ASP.NET的控件
- asp.net学习之Repeater控件
- asp中弹出对话框,确定后重定向方法
- asp 时间的比较如何选择出适合范围的时间
- ASP.NET中IsPostBack详解
- asp.net 调用echarts显示图表控件随浏览器自适应解决方案
- win7 spark运行本地程序文件出错 error:avaSparkContext. : java.lang.NullPointerException
- C# ASP.NET基类,常用类库及源代码
- Asp.Net MVC页面静态化功能实现二:用递归算法来实现
- Asp.net Session过期页面处理
- [ASP.NET] 将数据绑定到DropDownlist中的常见问题
- Asp.net 日历控件
- Encription
- 关于访问asp.net网站时登录后的奇怪问题
- 安全参透之旅第3章 OWASP工具使用
- 一个asp+ACCESS省市二级联动菜单程序
- asp怎么实现二级联动下拉菜单
- ASP.NET权限管理系统(FrameWork) 1.0.7
- ASP.NET Repeater 控件分页