通過《ASP.NET Web API的Controller是如何被創(chuàng)建的?》我們已經(jīng)對(duì)HttpController激活系統(tǒng)的核心對(duì)象有了深刻的了解,這些對(duì)象包括用于解析程序集和有效HttpController類型的AssembliesResolver和HttpControllerTypeResolver、根據(jù)請(qǐng)求完整目標(biāo)HttpController選擇的HttpControllerSelector、負(fù)責(zé)激活目標(biāo)HttpController實(shí)例的HttpControllerActivator、以及作為IoC容器的DependencyResolver。[本文已經(jīng)同步到《How ASP.NET Web API Works?》]
對(duì)于組成ASP.NET Web API核心框架的消息處理管道來說,處于末端的HttpMessageHandler是一個(gè)HttPRoutingDispatcher對(duì)象。當(dāng)它完成路由解析工作之后(HttpRoutingDispatcher的路由解析只發(fā)生在Self Host寄宿模式下,對(duì)于Web Host寄宿模式來說,路由解析工作是由ASP.NET路由系統(tǒng)來完成的),在默認(rèn)情況下它會(huì)將請(qǐng)求傳遞給一個(gè)HttpControllerDispatcher對(duì)象。 HttpControllerDispatcher實(shí)現(xiàn)了目標(biāo)HttpController對(duì)象的激活與執(zhí)行,并將代表執(zhí)行結(jié)果的HttpResponseMessage對(duì)象返回給HttpRoutingDispatcher對(duì)象,后者將此HttpResponseMessage回傳給消息管道進(jìn)行相應(yīng)處理后最終完成對(duì)請(qǐng)求的響應(yīng)。
右圖所示的UML體現(xiàn)了激活HttpController的整個(gè)流程。當(dāng)HttpControllerDispatcher接管請(qǐng)求之后,它會(huì)獲取注冊(cè)的HttpControllerSelector對(duì)象,并調(diào)用其SelectController方法得到描述目標(biāo)HttpController的HttpControllerDescriptor對(duì)象。
默認(rèn)注冊(cè)的HttpControllerSelector是一個(gè)DefaultHttpControllerSelector對(duì)象,后者借助于注冊(cè)的HttpControllerTypeResolver對(duì)象得到所有HttpController類型,進(jìn)而創(chuàng)建一個(gè)描述這些HttpController的HttpControllerDescriptor對(duì)象與HttpController名稱之間的映射關(guān)系。當(dāng)它的SelectController方法被執(zhí)行后,它只需要根據(jù)請(qǐng)求攜帶的HttpRouteData對(duì)象獲取目標(biāo)HttpController的名稱,并從此映射關(guān)系中選擇對(duì)應(yīng)的HttpControllerDescriptor即可。
HttpControllerDispatcher接下來調(diào)用這個(gè)HttpControllerDescriptor對(duì)象的CreateController方法得到激活的HttpController對(duì)象。對(duì)于這個(gè)HttpControllerDescriptor對(duì)象來說,當(dāng)它的CreateController方法被調(diào)用之后,它會(huì)獲取注冊(cè)的HttpControllerActivator對(duì)象,并調(diào)用其Create方法實(shí)現(xiàn)針對(duì)目標(biāo)HttpController對(duì)象的激活并將激活的對(duì)象返回。
默認(rèn)注冊(cè)的DefaultHttpControllerActivator對(duì)象會(huì)利用注冊(cè)的DependencyResolver根據(jù)HttpController類型去獲取代表目標(biāo)HttpController實(shí)例的對(duì)象。如果后者返回一個(gè)具體的HttpController對(duì)象,該對(duì)象將直接作為方法的返回值,否則DefaultHttpControllerActivator直接采用反射的形式創(chuàng)建目標(biāo)HttpController對(duì)象并返回。
由于默認(rèn)注冊(cè)的DependencyResolver是一個(gè)EmptyResolver對(duì)象,由它返回的HttpController對(duì)象總是Null,所以在默認(rèn)情況下激活的HttpController對(duì)象總是以反射的形式創(chuàng)建的。正因?yàn)槿绱耍覀兌x的HttpController類型必須具有一個(gè)默認(rèn)構(gòu)造函數(shù)。
我們知道作為自定義HttpController默認(rèn)基類的ApiController類型實(shí)現(xiàn)了IDispoable接口,資源釋放工作可以通過調(diào)用實(shí)現(xiàn)的Dispose方法來完成,那么這個(gè)方法是在什么時(shí)候執(zhí)行的呢?除此之外,我們知道表示請(qǐng)求的HttpRequestMessage類型具有一個(gè)字典類型的屬性Properties,我們可以利用它將任何一個(gè)對(duì)象附加到一個(gè)HttpRequestMessage對(duì)象上,如果這些附加對(duì)象需要實(shí)施資源釋放操作,這些操作又是在什么時(shí)候被執(zhí)行的呢?
實(shí)際上HttpRequestMessage通過Properties屬性表示的屬性字典為需要釋放的資源預(yù)留了存儲(chǔ)空間,對(duì)應(yīng)的Key為“MS_DisposableRequestResources”,對(duì)應(yīng)的值是一個(gè)List<IDisposable>的對(duì)象。我們可以調(diào)用HttpRequestMessage具有如下定義的擴(kuò)展方法GetResourcesForDisposal得到這個(gè)列表,也可以調(diào)用擴(kuò)展方法RegisterForDispose將一個(gè)或者多個(gè)類型實(shí)現(xiàn)了IDisposable接口的對(duì)象放到這個(gè)列表中。
1: public static class HttpRequestMessageExtensions
2: { 3: //其他成員
4: public static IEnumerable<IDisposable> GetResourcesForDisposal(this HttpRequestMessage request);
5:
6: public static void RegisterForDispose(this HttpRequestMessage request, IEnumerable<IDisposable> resources);
7: public static void RegisterForDispose(this HttpRequestMessage request,IDisposable resource);
8:
9: public static void DisposeRequestResources(this HttpRequestMessage request);
10: }
ASP.NET Web API還為釋放這些附加到HttpRequestMessage上的對(duì)象定義了如上一個(gè)擴(kuò)展方法DisposeRequestResources,那么這個(gè)方法究竟是在什么時(shí)候被調(diào)用的呢?
釋放這些資源的時(shí)機(jī)取決于采用的寄宿模式。對(duì)于Web Host來說,ASP.NET Web API用于“處理請(qǐng)求、回復(fù)響應(yīng)”的HttpMessageHandler管道是由HttpControllerHandler創(chuàng)建的,后者根據(jù)當(dāng)前HTTP上下文創(chuàng)建一個(gè)表示當(dāng)前請(qǐng)求的HttpRequestMessage對(duì)象并傳入這個(gè)管道進(jìn)行處理。在整個(gè)管道完成對(duì)請(qǐng)求的處理并最終對(duì)請(qǐng)求予以響應(yīng)之后,HttpControllerHandler會(huì)負(fù)責(zé)完成如下三項(xiàng)與資源釋放有關(guān)的工作。
對(duì)于Self Host來說,通過《Self Host模式下的ASP. NET Web API是如何進(jìn)行請(qǐng)求的監(jiān)聽與處理的?》的介紹我們知道請(qǐng)求的監(jiān)聽、接收和響應(yīng)是通過HttpBinding創(chuàng)建的信道棧來完成的。該信道棧處理的消息類型為HttpMessage,具體代表請(qǐng)求消息和響應(yīng)消息的HttpMessage分別是對(duì)HttpRequestMessage和HttpResponseMessage對(duì)象的封裝。WCF中表示消息的Message本身就是一個(gè)需要最
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注