当前位置:网站首页 > R语言数据分析 > 正文

xavier名字(xavier昵称)



假设我有一个应用场景:Core Framework可以用于任何区域的站点,其中的CustomersController有个取customer的fullname的方法GetFullName(),可想而知,这个api在中国和美国的站点上,应该得到不同的返回值。如下图所示:

web api namespace

这样的设计可以带来两个好处:

1、利用了OO的思想,可以封装各个区域customer service相关的一些公共逻辑

2、使得client端可以一致的接口访问服务,如:http://hostname/api/customers

这看上去不错,但是为了达到我的目的,就必须让web api支持在不同的namespace(或者area)中,存在相同名称的controller。但是web api默认情况下是不支持的,那么是否可以通过某种方法,使web api支持这种效果呢?答案是肯定的。

为了让web api支持namespace(或者area),就必须找到为什么默认情况下web api不支持,在这个过程中,也许能找到切入点。为了能找到原因,我做了如下工作:

从mvc4官网,找到了server端的request处理过程,如下图所示:

web api handlers

从图中我们可以看到,controller是通过HttpControllerDispatcher调度器,来处理的。

HttpControllerDispatcher 位于System.Web.Http.Dispatcher命名空间中,其源代码中有一个私有属性:

从代码中可以看出,该属性,只是简单的从services容器中,得到IHttpControllerSelector类型的一个对象,所以问题现在转移到在这个controllerselector对象上。

在this._configuration.Services.GetHttpControllerSelector();这条语句中,_configuration其实就是System.Web.Http.HttpConfiguration,在其构造函数中,可以看到:

DefaultServices为ServicesContainer的一个子类,所以可以称之为服务容器,定义在System.Web.Http.Services命名空间下,在其构造函数中,有如下代码:

从红色部分这正是我所需要的找的controllerselector。

从第2步中,如果通过源代码,可以发现:HttpControllerDispatcher 在处理request时,需要通过HttpControllerDescriptor对象的CreateController方法,才能最终实例化一个ApiController。而HttpControllerDescriptor是通过IHttpControllerSelector(默认就是DefaultHttpControllerSelector)的SelectController方法构造的。我进一步在DefaultHttpControllerSelector源码中,发现如下代码:

和HttpControllerTypeCache这样一个cache辅助类里的:

这就是问题所在,导致在同一个assembly中,不能有两个相同名字的api controller。否则就会执行:

controllerTypes.Count大于0,导致抛出“Multiple types were found that match the controller named…”异常。

到现在为止,其实解决办法已经出来了:就是不用上面的两个方法,来构造HttpControllerDispatcher。那么我们就只能自定义IHttpControllerSelector了。所以我自定义了一个NamespaceHttpControllerSelector用于支持namespace,源代码如下:

其实代码并不难懂,核心部分就是:

1、InitializeApiControllerCache方法,用于通过fullname为key,构造一个controller type的一个集合

2、GetControllerFullName方法,从namespace数组和_apiControllerCache集合中,取到符合条件的controller的fullname

到目前为止,我们的工作还剩下最后一步,就是用NamespaceHttpControllerSelector替换DefaultHttpControllerSelector,使其生效。通过以上的分析,其实也很明显了,只需要在Application_Start方法中,用DefaultServices继承下来的Replace即可:

至此,才算大功告成!

到此这篇xavier名字(xavier昵称)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • jvisualvm分析hprof文件(jvm profiler)2025-07-09 22:09:09
  • treedms破解版(tree world安卓破解版)2025-07-09 22:09:09
  • arg怎么读?(sports怎么读)2025-07-09 22:09:09
  • treesize free安装出现错误(source tree安装)2025-07-09 22:09:09
  • mouseleave 不响应(mousepressevent 不响应)2025-07-09 22:09:09
  • tornadoes翻译(torna a surriento翻译)2025-07-09 22:09:09
  • storey和story的区别(stories与story)2025-07-09 22:09:09
  • treesoft官网(treeswap官网)2025-07-09 22:09:09
  • airplay投屏电视(airplay投屏电视没反应)2025-07-09 22:09:09
  • git clone 版本(git clone release)2025-07-09 22:09:09
  • 全屏图片