ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver

來源:互聯網
上載者:User

標籤:

Message

WebAPI作為通訊架構必定包含包含請求與響應兩個方法上的報文,在WebAPI它們分別是HttpRequestMessage,HttpResponseMessage。對於HttpResponseMessage之前在WebAPI返回結果中有應用。

HttpRequestMessage

請求報文包含請求地址(RequestUri),要求方法(Method),頭資訊(Headers),報文資訊(Content)以及Http版本(Versions)

 

    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)

 

    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的擴充

 

 

    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的構造中注入的。

 

    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);}

 

 

    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.

 

        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 s 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 s 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的方法

 

    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

   

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預設就是採用直接反射方式.

 

ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.