WebAPI作为通信架构必定包含包含请求与响应两个方法上的报文,在WebAPI它们分别是HttpRequestMessage,HttpResponseMessage。对于HttpResponseMessage之前在WebAPI返回结果中有应用。
请求报文包含请求地址(RequestUri),请求方法(Method),头信息(Headers),报文信息(Content)以及Http版本(Versions)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |     publicclassHttpRequestMessage : IDisposable    {        publicHttpRequestMessage();               publicHttpRequestMessage(HttpMethod method, stringrequestUri);               publicHttpRequestMessage(HttpMethod method, Uri requestUri);        publicHttpContent Content { get; set; }               publicHttpRequestHeaders Headers { get; }            publicHttpMethod Method { get; set; }              publicIDictionary<string, object> Properties { get; }               publicUri RequestUri { get; set; }               publicVersion Version { get; set; }        publicvoidDispose();               protectedvirtualvoidDispose(booldisposing);              publicoverridestringToString();} | 
另外,WebAPI提供了一个类型为IDictionary<string,object>的属性Properties。我们可以将做任意对象作为附加属性添加到HttpRequestMessage.
请求报文包含状态码(StatusCode),原因短句(ReasonPhrase),头信息(Headers),报文信息(Content)以及Http版本(Versions)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |     publicclassHttpRequestMessage : IDisposable    {        publicHttpRequestMessage();               publicHttpRequestMessage(HttpMethod method, stringrequestUri);               publicHttpRequestMessage(HttpMethod method, Uri requestUri);        publicHttpContent Content { get; set; }               publicHttpRequestHeaders Headers { get; }            publicHttpMethod Method { get; set; }              publicIDictionary<string, object> Properties { get; }               publicUri RequestUri { get; set; }               publicVersion Version { get; set; }        publicvoidDispose();               protectedvirtualvoidDispose(booldisposing);              publicoverridestringToString();} | 
HttpConfiguration在WebAPI大概有如下几个作用:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | publicclassHttpConfiguration : IDisposable{    publicHttpConfiguration();    publicHttpConfiguration(HttpRouteCollection routes);    publicIDependencyResolver DependencyResolver { get; set; }    publicHttpFilterCollection Filters { get; }    publicMediaTypeFormatterCollection Formatters { get; }    publicIncludeErrorDetailPolicy IncludeErrorDetailPolicy { get; set; }    publicAction<HttpConfiguration> Initializer { get; set; }    publicCollection<System.Net.Http.DelegatingHandler> MessageHandlers { get; }    publicParameterBindingRulesCollection ParameterBindingRules { get; internalset; }    publicConcurrentDictionary<object, object> Properties { get; }    publicHttpRouteCollection Routes { get; }    publicServicesContainer Services { get; internalset; }    publicstringVirtualPathRoot { get; }    publicvoidDispose();    protectedvirtualvoidDispose(booldisposing);    publicvoidEnsureInitialized();} | 
对于第1 点我们在每6篇已经用到。第2点后面会陆续讲到,本篇只重点讲下第3点。这一功能主要是通过ServicesContainer来完成,即HttpConfiguration中的Services属性。
WebAPI对ServicesContainer的提供的派生类是DefaultServices,在DefaultServices,包含了两种依赖注入方法:1,单一派生类型注入(multi),2,多派生类型注入(single),即在注入派生类型的数量有区别。比如在获取url参数的时候有QueryString,RouteData两种方式,而这两种方式是通过QueryStringValueProvider与RouteDataValueProvider两种类型来实现的(实际在DefaultServices注入是这人两个类对应的Factory类),这两种类型属于平行关系,所以这个时候能需要采用multi方法注入。
这些类型都是在DefaultServces的构造中注入的。
| 1 2 3 4 5 6 7 8 9 10 11 12 |     publicclassDefaultServices : ServicesContainer    {        protectedDefaultServices();        publicDefaultServices(HttpConfiguration configuration);        protectedoverridevoidClearSingle(Type serviceType);        publicoverrideobjectGetService(Type serviceType);        protectedoverrideList<object> GetServiceInstances(Type serviceType);        publicoverrideIEnumerable<object> GetServices(Type serviceType);        publicoverrideboolIsSingleService(Type serviceType);        protectedoverridevoidReplaceSingle(Type serviceType, objectservice);        protectedoverridevoidResetCache(Type serviceType);} | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |     publicabstractclassServicesContainer : IDisposable    {        protectedServicesContainer();        publicvoidAdd(Type serviceType, objectservice);        publicvoidAddRange(Type serviceType, IEnumerable<object> services);        publicvirtualvoidClear(Type serviceType);        publicvirtualvoidDispose();        publicintFindIndex(Type serviceType, Predicate<object> match);        publicabstractobjectGetService(Type serviceType);        publicabstractIEnumerable<object> GetServices(Type serviceType);        publicvoidInsert(Type serviceType, intindex, objectservice);viceType, intindex, IEnumerable<object> services);        publicabstractboolIsSingleService(Type serviceType);        publicboolRemove(Type serviceType, objectservice);        publicintRemoveAll(Type serviceType, Predicate<object> match);        publicvoidRemoveAt(Type serviceType, intindex);        publicvoidReplace(Type serviceType, objectservice);        publicvoidReplaceRange(Type serviceType, IEnumerable<object> services);    } | 
ServicesContainer只提供的了替换与获取的公共方法。因为ServicesContainer只提供了WebAPI中的标准组件,并不想作为一个公共的Ioc容器,而这些标准的组件是WebAPI进行扩展的基础。
下面我写的四个Action分别是获取所有multiServices,获取所有singleServices,向multiServices中添加一个自定义的ValueProviderFactory,向singleServices中添加自定义的IExceptionHandler.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | publicDictionary<Type, List<Type>> GetAllMultiServices(){    Dictionary<Type, List<Type>> result = newDictionary<Type, List<Type>>();    FieldInfo field = RequestContext.Configuration.Services.GetType().GetField("_defaultServicesMulti",        BindingFlags.NonPublic|BindingFlags.Instance);    Dictionary<Type, List<object>> multiServices = (Dictionary<Type, List<object>>)field.GetValue(RequestContext.Configuration.Services);    foreach(vars inmultiServices)    {        List<Type> items = newList<Type>();        foreach(varitem ins.Value) {            items.Add(item.GetType());        }        result[s.Key] = items;    }    returnresult;}publicDictionary<Type, Type> GetAllSingleServices(){    Dictionary<Type, Type> result = newDictionary<Type, Type>();    FieldInfo field = RequestContext.Configuration.Services.GetType().GetField("_defaultServicesSingle",        BindingFlags.NonPublic | BindingFlags.Instance);    Dictionary<Type, object> services = (Dictionary<Type, object>)field.GetValue(RequestContext.Configuration.Services);    foreach(vars inservices)    {                result.Add(s.Key, s.Value==null?null:s.Value.GetType());    }    returnresult;}publicDictionary<Type, List<Type>> AddMultiService(){    List<ValueProviderFactory> valueProviderFactories=newList<ValueProviderFactory>(){    newQueryStringValueProviderFactory(),    newRouteDataValueProviderFactory(),    newMyValueProviderFactory()    };    RequestContext.Configuration.Services.ReplaceRange(typeof(ValueProviderFactory), valueProviderFactories);    returnGetAllMultiServices();}publicDictionary<Type, Type> ReplaceSingleService(){    RequestContext.Configuration.Services.Replace(typeof(IExceptionHandler), newMyExceptionHandler());    returnGetAllSingleServices();} | 
因为ServicesContainer中的类型注入都是固定的,所以WebAPI给ServicesContainer扩展了一组获取Service的方法
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | publicstaticclassServicesExtensions{    publicstaticIHttpActionInvoker GetActionInvoker(thisServicesContainer services);    publicstaticIHttpActionSelector GetActionSelector(thisServicesContainer services);    publicstaticIActionValueBinder GetActionValueBinder(thisServicesContainer services);    publicstaticIApiExplorer GetApiExplorer(thisServicesContainer services);    publicstaticIAssembliesResolver GetAssembliesResolver(thisServicesContainer services);    publicstaticIBodyModelValidator GetBodyModelValidator(thisServicesContainer services);    publicstaticIContentNegotiator GetContentNegotiator(thisServicesContainer services);    publicstaticIDocumentationProvider GetDocumentationProvider(thisServicesContainer services);    publicstaticIExceptionHandler GetExceptionHandler(thisServicesContainer services);    publicstaticIEnumerable<IExceptionLogger> GetExceptionLoggers(thisServicesContainer services);    publicstaticIEnumerable<System.Web.Http.Filters.IFilterProvider> GetFilterProviders(thisServicesContainer services);    publicstaticIHostBufferPolicySelector GetHostBufferPolicySelector(thisServicesContainer services);    publicstaticIHttpControllerActivator GetHttpControllerActivator(thisServicesContainer services);    publicstaticIHttpControllerSelector GetHttpControllerSelector(thisServicesContainer services);    publicstaticIHttpControllerTypeResolver GetHttpControllerTypeResolver(thisServicesContainer services);    publicstaticIEnumerable<System.Web.Http.ModelBinding.ModelBinderProvider> GetModelBinderProviders(thisServicesContainer services);    publicstaticModelMetadataProvider GetModelMetadataProvider(thisServicesContainer services);    publicstaticIEnumerable<ModelValidatorProvider> GetModelValidatorProviders(thisServicesContainer services);    publicstaticITraceManager GetTraceManager(thisServicesContainer services);    publicstaticITraceWriter GetTraceWriter(thisServicesContainer services);    publicstaticIEnumerable<System.Web.Http.ValueProviders.ValueProviderFactory> GetValueProviderFactories(thisServicesContainer services);} | 
在ASP.NET WebAPI中有一个GlobalConfiguration,其实它并不是WebAPI的一部分。WebAPI只是一个独立的框架。它需要寄宿在别的应用程序下才能运行。寄宿模式则分为两种WebHost,SelfHost,WebHost是针对Web程序的寄宿。因为本系列只讨论ASP.Net下的WebAPI,所以只简单讲一下WebHost模式。
ASP.NET WebAPI中引用了程序集System.Web.Http.WebHost,GlobalConfiguration就在该程序集下.它包含了一个HttpConfiguration属性.还一个配置HttpConfiguration的方法
另外还有一个HttServer
另外在ApiController的很多属性都能找到HttpConfiguraiton
Configuration
ControllerContext.Configuration
RequestContext.Configuration
这些HttpConfiguration都来自对GlobalConfiguration.Configuration的引用.
WebAPI为我们提供了一个Ioc框架,即DependencyResolver
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | publicinterfaceIDependencyResolver : IDependencyScope, IDisposable {IDependencyScope BeginScope(); }publicinterfaceIDependencyScope : IDisposable {objectGetService(Type serviceType);IEnumerable<object> GetServices(Type serviceType); } | 
IDependencyResolver也继承了IDependencyScope,所以我们可以将IDependencyScope视为依赖的上下文.
在WebAPI中DependencyResolver并没有像其它组件一样注册在ServicesContainer中,而是直接注册在HttpConfiguration中(DependencyResolver属性).
别个HttpRequestMessage中也有一扩展方法GetDependencyScope来获取DependencyScope,该方法获取的是HttpRequestMessage的Properties的DependencyResolver,这里的DependencyResolver也来自HttpConfiguration.
在WebAPI中也定义了一个EmptyResolver,它只是一个空的Resolver,所以在WebAPI默认就是采用直接反射方式.
Github: https://github.com/BarlowDu/WebAPI (API_8)
ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver
原文:http://www.cnblogs.com/shiningrise/p/5585927.html