ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver

ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver

 

Message

WebAPI作为通信架构必定包含包含请求与响应两个方法上的报文,在WebAPI它们分别是HttpRequestMessage,HttpResponseMessage。对于HttpResponseMessage之前在WebAPI返回结果中有应用。

HttpRequestMessage

请求报文包含请求地址(RequestUri),请求方法(Method),头信息(Headers),报文信息(Content)以及Http版本(Versions)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     public  class  HttpRequestMessage : IDisposable
     {
         public  HttpRequestMessage();       
         public  HttpRequestMessage(HttpMethod method,  string  requestUri);       
         public  HttpRequestMessage(HttpMethod method, Uri requestUri);
         public  HttpContent Content {  get set ; }       
         public  HttpRequestHeaders Headers {  get ; }    
         public  HttpMethod Method {  get set ; }      
         public  IDictionary< string object > Properties {  get ; }       
         public  Uri RequestUri {  get set ; }       
         public  Version Version {  get set ; }
         public  void  Dispose();       
         protected  virtual  void  Dispose( bool  disposing);      
         public  override  string  ToString();
}

 

 

 

另外,WebAPI提供了一个类型为IDictionary<string,object>的属性Properties。我们可以将做任意对象作为附加属性添加到HttpRequestMessage.

 

HttpResponseMessage

请求报文包含状态码(StatusCode),原因短句(ReasonPhrase),头信息(Headers),报文信息(Content)以及Http版本(Versions)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     public  class  HttpRequestMessage : IDisposable
     {
         public  HttpRequestMessage();       
         public  HttpRequestMessage(HttpMethod method,  string  requestUri);       
         public  HttpRequestMessage(HttpMethod method, Uri requestUri);
         public  HttpContent Content {  get set ; }       
         public  HttpRequestHeaders Headers {  get ; }    
         public  HttpMethod Method {  get set ; }      
         public  IDictionary< string object > Properties {  get ; }       
         public  Uri RequestUri {  get set ; }       
         public  Version Version {  get set ; }
         public  void  Dispose();       
         protected  virtual  void  Dispose( bool  disposing);      
         public  override  string  ToString();
}

 

 

 

 

 

HttpConfiguration

HttpConfiguration在WebAPI大概有如下几个作用:

  1. 设置通信管道
  2. 存储全局信息(比如Filter,Route,Formatter)
  3. 提供一个Ioc架构,用于WebAPI的扩展

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public  class  HttpConfiguration : IDisposable
{
     public  HttpConfiguration();
     public  HttpConfiguration(HttpRouteCollection routes);
     public  IDependencyResolver DependencyResolver {  get set ; }
     public  HttpFilterCollection Filters {  get ; }
     public  MediaTypeFormatterCollection Formatters {  get ; }
     public  IncludeErrorDetailPolicy IncludeErrorDetailPolicy {  get set ; }
     public  Action<HttpConfiguration> Initializer {  get set ; }
     public  Collection<System.Net.Http.DelegatingHandler> MessageHandlers {  get ; }
     public  ParameterBindingRulesCollection ParameterBindingRules {  get internal  set ; }
     public  ConcurrentDictionary< object object > Properties {  get ; }
     public  HttpRouteCollection Routes {  get ; }
     public  ServicesContainer Services {  get internal  set ; }
     public  string  VirtualPathRoot {  get ; }
     public  void  Dispose();
     protected  virtual  void  Dispose( bool  disposing);
     public  void  EnsureInitialized();
}

 

 

 

对于第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
     public  class  DefaultServices : ServicesContainer
     {
         protected  DefaultServices();
         public  DefaultServices(HttpConfiguration configuration);
         protected  override  void  ClearSingle(Type serviceType);
         public  override  object  GetService(Type serviceType);
         protected  override  List< object > GetServiceInstances(Type serviceType);
         public  override  IEnumerable< object > GetServices(Type serviceType);
         public  override  bool  IsSingleService(Type serviceType);
         protected  override  void  ReplaceSingle(Type serviceType,  object  service);
         protected  override  void  ResetCache(Type serviceType);
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     public  abstract  class  ServicesContainer : IDisposable
     {
         protected  ServicesContainer();
         public  void  Add(Type serviceType,  object  service);
         public  void  AddRange(Type serviceType, IEnumerable< object > services);
         public  virtual  void  Clear(Type serviceType);
         public  virtual  void  Dispose();
         public  int  FindIndex(Type serviceType, Predicate< object > match);
         public  abstract  object  GetService(Type serviceType);
         public  abstract  IEnumerable< object > GetServices(Type serviceType);
         public  void  Insert(Type serviceType,  int  index,  object  service);
viceType,  int  index, IEnumerable< object > services);
         public  abstract  bool  IsSingleService(Type serviceType);
         public  bool  Remove(Type serviceType,  object  service);
         public  int  RemoveAll(Type serviceType, Predicate< object > match);
         public  void  RemoveAt(Type serviceType,  int  index);
         public  void  Replace(Type serviceType,  object  service);
         public  void  ReplaceRange(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
public  Dictionary<Type, List<Type>> GetAllMultiServices()
{
     Dictionary<Type, List<Type>> result =  new  Dictionary<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  ( var  in  multiServices)
     {
         List<Type> items =  new  List<Type>();
         foreach  ( var  item  in  s.Value) {
             items.Add(item.GetType());
         }
         result[s.Key] = items;
     }
     return  result;
}
 
public  Dictionary<Type, Type> GetAllSingleServices()
{
     Dictionary<Type, Type> result =  new  Dictionary<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  ( var  in  services)
     {
         
         result.Add(s.Key, s.Value== null ? null :s.Value.GetType());
     }
     return  result;
}
 
public  Dictionary<Type, List<Type>> AddMultiService()
{
     List<ValueProviderFactory> valueProviderFactories= new  List<ValueProviderFactory>(){
     new  QueryStringValueProviderFactory(),
     new  RouteDataValueProviderFactory(),
     new  MyValueProviderFactory()
     };
     RequestContext.Configuration.Services.ReplaceRange( typeof (ValueProviderFactory), valueProviderFactories);
     return  GetAllMultiServices();
}
 
public  Dictionary<Type, Type> ReplaceSingleService()
{
     RequestContext.Configuration.Services.Replace( typeof (IExceptionHandler),  new  MyExceptionHandler());
     return  GetAllSingleServices();
}

 

 

 

 

因为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
public  static  class  ServicesExtensions
{
     public  static  IHttpActionInvoker GetActionInvoker( this  ServicesContainer services);
     public  static  IHttpActionSelector GetActionSelector( this  ServicesContainer services);
     public  static  IActionValueBinder GetActionValueBinder( this  ServicesContainer services);
     public  static  IApiExplorer GetApiExplorer( this  ServicesContainer services);
     public  static  IAssembliesResolver GetAssembliesResolver( this  ServicesContainer services);
     public  static  IBodyModelValidator GetBodyModelValidator( this  ServicesContainer services);
     public  static  IContentNegotiator GetContentNegotiator( this  ServicesContainer services);
     public  static  IDocumentationProvider GetDocumentationProvider( this  ServicesContainer services);
     public  static  IExceptionHandler GetExceptionHandler( this  ServicesContainer services);
     public  static  IEnumerable<IExceptionLogger> GetExceptionLoggers( this  ServicesContainer services);
     public  static  IEnumerable<System.Web.Http.Filters.IFilterProvider> GetFilterProviders( this  ServicesContainer services);
     public  static  IHostBufferPolicySelector GetHostBufferPolicySelector( this  ServicesContainer services);
     public  static  IHttpControllerActivator GetHttpControllerActivator( this  ServicesContainer services);
     public  static  IHttpControllerSelector GetHttpControllerSelector( this  ServicesContainer services);
     public  static  IHttpControllerTypeResolver GetHttpControllerTypeResolver( this  ServicesContainer services);
     public  static  IEnumerable<System.Web.Http.ModelBinding.ModelBinderProvider> GetModelBinderProviders( this  ServicesContainer services);
     public  static  ModelMetadataProvider GetModelMetadataProvider( this  ServicesContainer services);
     public  static  IEnumerable<ModelValidatorProvider> GetModelValidatorProviders( this  ServicesContainer services);
     public  static  ITraceManager GetTraceManager( this  ServicesContainer services);
     public  static  ITraceWriter GetTraceWriter( this  ServicesContainer services);
     public  static  IEnumerable<System.Web.Http.ValueProviders.ValueProviderFactory> GetValueProviderFactories( this  ServicesContainer 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的引用.

 

 

DependencyResolver

WebAPI为我们提供了一个Ioc框架,即DependencyResolver

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  interface  IDependencyResolver : IDependencyScope, IDisposable
 
  {
 
IDependencyScope BeginScope();
 
  }
 
public  interface  IDependencyScope : IDisposable
 
  {
 
object  GetService(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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值