Fork me on GitHub
ASP.NET Web API的HttpController是如何被激活的?

ASP.NET Web API的HttpController是如何被激活的?

HttpController与HttpControllerDescriptor 
程序集的解析 
HttpController类型的解析 
目标HttpController类型的选择 
目标HttpController的创建

通过上面的内容我们已经对HttpController激活系统的核心对象有了深刻的了解,这些对象包括用于解析程序集和有效HttpController类型的AssembliesResolver和HttpControllerTypeResolver,根据请求完整目标HttpController选择的HttpControllerSelector,负责激活目标HttpController实例的HttpControllerActivator,以及作为IoC容器的DependencyResolver。

右图所示的UML揭示上述这些核心对象对应的接口和类型,以及它们之间的关系。当接收到的请求流经消息管道并作相应处理之后,上述这些对象相互协作完成了针对目标HttpConrtoller的激活工作,那么ASP.NET Web API具体具有怎样一个HttpController激活流程呢?

对于组成ASP.NET Web API核心框架的消息处理管道来说,处于末端的HttpMessageHandler是一个HttpRoutingDispatcher对象。当它完成路由解析工作之后(HttpRoutingDispatcher的路由解析只发生在Self Host寄宿模式下,对于Web Host寄宿模式来说,路由解析工作是由ASP.NET路由系统来完成的),在默认情况下它会将请求传递给一个HttpControllerDispatcher对象。

HttpControllerDispatcher实现了目标HttpController对象的激活与执行,并将代表执行结果的HttpResponseMessage对象返回给HttpRoutingDispatcher对象,后者将此HttpResponseMessage回传给消息管道进行相应处理后最终完成对请求的响应。

左图所示的UML体现了激活HttpController的整个流程。当HttpControllerDispatcher接管请求之后,它会获取注册的HttpControllerSelector对象,并调用其SelectController方法得到描述目标HttpController的HttpControllerDescriptor对象。

默认注册的HttpControllerSelector是一个DefaultHttpControllerSelector对象,后者借助于注册的HttpControllerTypeResolver对象得到所有HttpController类型,进而创建一个描述这些HttpController的HttpControllerDescriptor对象与HttpController名称之间的映射关系。当它的SelectController方法被执行后,它只需要根据请求携带的HttpRouteData对象获取目标HttpController的名称,并从此映射关系中选择对应的HttpControllerDescriptor即可。

HttpControllerDispatcher接下来调用这个HttpControllerDescriptor对象的CreateController方法得到激活的HttpController对象。对于这个HttpControllerDescriptor对象来说,当它的CreateController方法被调用之后,它会获取注册的HttpControllerActivator对象,并调用其Create方法实现针对目标HttpController对象的激活并将激活的对象返回。

对于默认注册的DefaultHttpControllerActor对象来说,它会利用注册的DependencyResolver根据HttpController类型去获取代表目标HttpController实例的对象。如果后者返回一个具体的HttpController对象,该对象将直接作为方法的返回值,否则DefaultHttpControllerActor直接采用反射的形式创建目标HttpController对象并返回。

由于默认注册的DependencyResolver是一个EmptyResolver对象,由它返回的HttpController对象总是Null,所以在默认情况下激活的HttpController对象总是以反射的形式创建的。正因为如此,我们定义的HttpController类型必须具有一个默认构造函数。

作者:Artech
posted on 2014-01-28 00:26  HackerVirus  阅读(323)  评论(0编辑  收藏  举报