ASP.NET Web API 控制器创建过程(二)

ASP.NET Web API 控制器创建过程(二)

前言

本来这篇随笔应该是在上周就该写出来公布的,因为身体跟不上节奏感冒发烧有心无力,这样的天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病去如抽丝。这两天状态才好了一点,让我理解了什么才是革命的本钱,希望大家也多保重身体。

好了,还是回归主题,对于上一篇的内容解说的仅仅是ASP.NET Web API控制器创建过程中的一个局部知识,在接着上篇内容解说的之前,我会先回想一下上篇的内容,而且在本篇里进行整合,让我们要看到的是一个整个的创建过程。

ASP.NET Web API 控制器创建、激活过程

  • ASP.NET Web API 控制器创建过程(一)
  • ASP.NET Web API 控制器创建过程()

创建、激活过程

图1

在前面的篇幅中我们说过APIController是由HttpControllerDispatcher类型来创建的,这仅仅是表面上的,图1中显示的就是控制器创建的整个过程了,我们先来回想一下上一篇所讲的,不然会认为不连贯,在回想的同一时候也会对图1进行解说。

首先我们来分解图1,能够把图1中分为两个部分,

第一个部分就是HttpConfiguration类型所表示的部分。如图2

图2

先来解释一下HttpConfiguration部分,在HttpConfiguration类型中有两个属性,第一个是ServicesContainer类型的属性Services,第二个就是IDependencyResolver类型的属性DependencyResolver,对于Services属性的类型在上篇中我也说过了,就是一个IoC容器,从HttpConfiguration类型角度来看就是一个依赖注入到HttpConfiguration中的IoC容器,对于DependencyResolver属性来说也差点儿相同就是这个意思了。

仅仅只是Services这个容器中存放的大多都是ASP.NET Web API框架中做一些基础工作的类型。

就好像上篇中说到的,在ASP.NET Web API框架中载入控制器所在程序集的时候我们就是使用自己定义的工作项替换掉了Services容器中的默认工作项:

selfHostServer.Configuration.Services.Replace(typeof(IAssembliesResolver),
                   newCustomAssembliesResolver.LoadSpecifiedAssembliesResolver());

这里从图2中能够看出默认的DefaultAssembliesResolver类型来运行这项工作的。

到这里也就是上个篇幅中的主要内容了。以下我们还是继续分解图1,上面说了第一部分了以下来看第二部分,第二个部分就是HttpControllerDispatcher类型到APIController类型的生成过程,也就是图1了。

首先我们的ASP.NET Web API框架会从HttpConfiguration中的Services容器中获取一个ControllerSelector(控制器选择器),这个控制器选择器呢相应的类型大家从图2中也能够看到,图1中也有,非常明了。

那么ControllerSelector主要干什么呢?肯定是选择控制器阿,当然了依据请求选择对应的控制器是主要功能,次要功能是啥?次要功能是生成控制器缓存,不然从哪选阿对不。在ASP.NET MVC框架中控制器缓存是存在xml文件里的,如今非常好奇在ASP.NET Web API框架中控制器缓存是什么样的存储方式呢?

我们就来看一下控制器选择器次要功能。

控制器选择器次要功能

首先我们先说明一下缓存的类型为ConcurrentDictionary<string, HttpControllerDescriptor>类型,就是一个一一相应的键值队,string表示着控制器名称,而HttpControllerDescriptor表示着相应控制器的控制器描写叙述类型,这个类型非常重要稍后再说,我们先要了解ConcurrentDictionary<string, HttpControllerDescriptor>缓存的由来。

首先在我们控制器选择器实例化的时候,在控制器选择器的构造函数中已经使用了延迟载入技术对控制器缓存进行了创建,详细的创建过程能够在图1看到,是由DefaultAssembliesResolver类型(或者是我们自己定义的工作项)载入指定的程序集,而且交由DefaultHttpControllerTypeResolver类型依据ASP.NET Web API框架中默认的搜索过滤条件返回载入程序集中的全部符合条件的控制器类型(ControllerTypes),来看演示样例。

所用项目结构还是上个篇幅的演示样例:

图3

图4

在图4中我们额外定义了一些控制器类型,然后在SelfHost端定义例如以下演示样例代码:

代码1-1

        staticvoidWriterControllerTypeMessage(HttpSelfHostServerselfHostServer)
        {

            ICollection<Type>types=selfHostServer.Configuration.Services.GetHttpControllerTypeResolver().GetControllerTypes(selfHostServer.Configuration.Services.GetAssembliesResolver());
            foreach (Typetypeintypes)
            {
                Console.WriteLine(type.Namespace+"_______"+type.Name);
            }
        }

而且在注冊端调用此静态函数:

using (HttpSelfHostServerselfHostServer=newHttpSelfHostServer(selfHostConfiguration))
            {
                selfHostServer.Configuration.Routes.MapHttpRoute(
                    "DefaultApi", "api/{controller}/{id}", new { id=RouteParameter.Optional });

                selfHostServer.Configuration.Services.Replace(typeof(IAssembliesResolver),
                    newCustomAssembliesResolver.LoadSpecifiedAssembliesResolver());

                WriterControllerTypeMessage(selfHostServer);

                selfHostServer.OpenAsync();
                Console.WriteLine("server端服务监听已开启");
                Console.Read();
            }

结果如图5:

图5

在我们获取了ControllerTypes过后了,ASP.NET Web API框架中有个HttpControllerTypeCache类型的对象就藏不住了,之前的一些操作都是由HttpControllerTypeCache类型去处理的,而在HttpControllerTypeCache获取了ControllerTypes过后就要做一个非常重要的工作了,就是对ControllerTypes进行分组操作最后返回一个Dictionary<string, ILookup<string,
Type>>类型的对象,就拿上面的演示样例来说吧,最后经过分组后的Dictionary<string, ILookup<string, Type>>类型值应该是:

Writer-->NameSpaceControllerOne->WriterController

NameSpaceControllerTwo->WriterController

Read-->NameSpaceControllerOne->ReadController

WriterAndRead-->NameSpaceControllerThree->WriterAndReadController

Product-->WebAPIController->ProductController

这个时候的值并非终于的缓存类型,而是通过我们的控制器选择器依据HttpControllerTypeCache类型所生成的Dictionary<string,ILookup<string, Type>>类型值来生成ConcurrentDictionary<string, HttpControllerDescriptor>缓存类型,还是依据上面的演示样例,我们看一下最后生成的缓存类型值。

改动1-1例如以下演示样例代码:

代码1-2

staticvoidWriterControllerTypeMessage(HttpSelfHostServerselfHostServer)
        {

            ICollection<Type>types=selfHostServer.Configuration.Services.GetHttpControllerTypeResolver().GetControllerTypes(selfHostServer.Configuration.Services.GetAssembliesResolver());
            foreach (Typetypeintypes)
            {
                Console.WriteLine(type.Namespace+"_______"+type.Name);
            }

            //Dictionary<string,ILookup<string, Type>> controllertypecache = types.GroupBy<Type,string>(t => t.Name,StringComparer.OrdinalIgnoreCase).ToDictionary<IGrouping<string,Type>, string, ILookup<string, Type>>
            //        (g => g.Key,
            //        g => g.ToLookup<Type,string>(t => (t.Namespace ?? string.Empty),StringComparer.OrdinalIgnoreCase), StringComparer.OrdinalIgnoreCase);

            //foreach(var value in controllertypecache)
            //{
            //    foreach (var val in value.Value)
            //    {

            //    }
            //}

            IDictionary<string, HttpControllerDescriptor>mapping=selfHostServer.Configuration.Services.GetHttpControllerSelector().GetControllerMapping();

            foreach (varmeginmapping)
            {
                Console.WriteLine("ControllerName:"+meg.Key+".ControllerTypeName:"+meg.Value.ControllerType.Name);
            }

        }

结果如图6:

图6

(在代码1-2中凝视掉的部分就是能够查看对ControllerTypes进行分组操作返回Dictionary<string, ILookup<string, Type>>类型的值)。

控制器选择器主要功能

次要功能看完之后,主要功能想必大家也是非常明了吧,在有了控制器缓存对象过后,控制器选择器则会依据HttpRequestMessage对象中的路由数据对象获取控制器名称,然后从缓存中获取到相应的HttpControllerDescriptor类型实例。

详细生成工作

在获取到了HttpControllerDescriptor类型实例过后生成IHttpController的工作就变得非常easy了,还是从HttpConfiguration中的Services容器中获得相应的负责控制器生成激活的工作项,在图1中能够明白的看出是DefaultHttpControllerActivator类型,在DefaultHttpControllerActivator类型工作的时候它会从HttpConfiguration中获取DependencyResolver属性相应的容器,假设这里的情况不满足才会调用后面的TypeActivator来生成激活IHttpController(通过反射)。

作者:金源

出处:http://blog.csdn.net/jinyuan0829

本文版权归作者和CSDN共同拥有,欢迎转载,但未经作者允许必须保留此段声明,且在文章页面

时间: 2024-10-03 23:07:05

ASP.NET Web API 控制器创建过程(二)的相关文章

ASP.NET Web API 控制器创建过程(一)

ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内容会为大家讲解第一个部分,也是ASP.NET Web API框架跟ASP.NET MVC框架实现上存在不同的一部分. ASP.NET Web API 控制器创建.激活过程 ASP.NET Web API 控制器创建过程(一) ASP.NET Web API 控制器创建过程(二) 未完待续 环境描述.

ASP.NETWeb API 控制器创建过程(二)

ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病去如抽丝.这两天状态才好了一点,让我理解了什么才是革命的本钱,希望大家也多保重身体. 好了,还是回归主题,对于上一篇的内容讲解的只是ASP.NET Web API控制器创建过程中的一个局部知识,在接着上篇内容讲解的之前,我会先回顾一下上篇的内容,并且在本篇里进行整合,让我们要看到的是一个整个的创建过

ASP.NET Web API 控制器执行过程(一)

ASP.NET Web API 控制器执行过程(一) 前言 前面两篇讲解了控制器的创建过程,只是从框架源码的角度去简单的了解,在控制器创建过后所执行的过程也是尤为重要的,本篇就来简单的说明一下控制器在创建过后将会做哪些工作. ASP.NET Web API 控制器执行过程 l  ASP.NET Web API 控制器执行过程(一) l ASP.NET Web API 控制器执行过程(二) 控制器执行过程 我们知道控制器的生成过程都是在HttpControllerDispatcher类型中来操作的

ASP.NET Web API 过滤器创建、执行过程(二)

前言 前面一篇中讲解了过滤器执行之前的创建,通过实现IFilterProvider注册到当前的HttpConfiguration里的服务容器中,当然默认的基础服务也是有的,并且根据这些提供程序所获得的的过滤器信息集合进行排序.本篇就会对过滤器在创建完之后所做的一系列操作进行讲解. ASP.NET Web API 过滤器创建.执行过程(二) FilterGrouping过滤器分组类型 FilterGrouping类型是ApiController类型中的私有类型,它的作用就如同它的命名一样,用来对过

ASP.NET Web API 过滤器创建、执行过程(一)

前言 在上一篇中我们讲到控制器的执行过程系列,这个系列要搁置一段时间了,因为在控制器执行的过程中包含的信息都是要单独的用一个系列来描述的,就如今天的这个篇幅就是在上面内容之后所看到的一个知识要点之一. ASP.NET Web API 过滤器创建.执行过程(一) 下面就来讲解一下在ASP.NET Web API框架中过滤器的创建.执行过程. 过滤器所在的位置 图1 图1所示的就是控制器执行过程很粗略的表示. 通过上一篇内容我们了解到控制器方法选择器最后返回的并不是控制器方法,而是对于控制器方法描述

细说Asp.Net Web API消息处理管道(二)

在细说Asp.Net Web API消息处理管道这篇文章中,通过翻看源码和实例验证的方式,我们知道了Asp.Net Web API消息处理管道的组成类型以及Asp.Net Web API是如何创建消息处理管道的.本文在上篇的基础上进行一个补充,谈谈在WebHost寄宿方式和SelfHost寄宿方式下,请求是如何进入到Asp.Net Web API的消息处理管道的. WebHost寄宿方式: 在剖析Asp.Net WebAPI路由系统一文中,我们知道Asp.Net Web API在WebHost寄

[转]使用ASP.NET Web API 2创建OData v4 终结点

本文转自:http://www.cnblogs.com/farb/p/ODataAspNetWebAPI.html 开放数据协议(Open Data Protocol[简称OData])是用于Web的数据访问协议.OData提供了一种对数据集进行CRUD操作(Create,Read,Update,Delete)的统一方式.Asp.Net Web API支持该协议的v3 和v4版,甚至可以创建一个和v3终结点并排运行的v4终结点.该博文演示了如何创建支持CRUD操作的OData v4终结点. 用到

asp.net web api 控制器

1控制器操作的参数 控制器操作的参数可以是内置类型也可以是自定义类型,无参也是允许的. 2控制器操作返回值 类型 说明 void 操作返回值为void时,Web API返回空HTTP响应,其状态码为204(无内容) HttpResponseMessage Web api会将此返回值直接转换为HTTP消息 IHttpActionResult 接口形式 内置类型或自定义类型 无   2.1返回值为HttpResponseMessage 返回值为此类型时,有两种设置方式. 第一种调用HttpRespo

Asp.Net Web API 2第十二课——Media Formatters媒体格式化器

前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本教程演示如何在ASP.NET Web API中支持额外的媒体格式. Internet Media Types——Internet的媒体类型 媒体类型,也叫做MIME类型,标识了一片数据的格式.在HTTP中,媒体类型描述了消息体的格式.一个媒体类型由两个字符串组成:类型和子类型.例如: text/html image/png