博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver
阅读量:5964 次
发布时间:2019-06-19

本文共 10333 字,大约阅读时间需要 34 分钟。

 

Message

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

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:  (API_8)

转载地址:http://wvjax.baihongyu.com/

你可能感兴趣的文章
张军-大数据的理解与分布式进化计算方法
查看>>
spring基础
查看>>
微信用户名乱码问题
查看>>
dubbo remoting(2)
查看>>
maya pyside 多个窗口实例 报错 解决
查看>>
关于文件上传请求第一次为post,后面为get的问题
查看>>
【Qt笔记】QDialog--模态和非模态
查看>>
nginx 0.8.54/1.0.0 在cygwin环境下的编译(包括 nginx_mod_h264
查看>>
PowerDesigner生成Excel版本的数据库文件
查看>>
Oracle 查找常见耗性能的语句
查看>>
java 通过反射获取调用类方法及属性
查看>>
thinkphp 开启页面的Trace信息
查看>>
mysql 链接数满了的错误 ERROR 1040 (HY000): Too many connections
查看>>
android textview字体加下划线
查看>>
springMVC 定时任务
查看>>
Mint8(ubuntu16.04) 搭建微信Web开发工具
查看>>
PostgreSQL数据类型-数据类型简介和布尔类型
查看>>
PostgreSQL数据类型-二进制数据和字符串数据类型与字符串函数
查看>>
安装应用的时候拷贝一个DB文件到应用database下
查看>>
shell 基础
查看>>