MVC核心功能组件和简介
依賴注入
與 MVC 類似, Web API 提供了System.Web.Http.Services.IDependencyResolver 接口來實現依賴注入, 我們可以很容易的用 Unity 來實現這個接口:
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class UnityDependencyResolver : IDependencyResolver { ?? ???private readonly IUnityContainer _container; ?? ???public UnityDependencyResolver(IUnityContainer container) { ??????this._container = container; ???} ?? ???public object GetService(Type serviceType) { ??????return this._container.IsRegistered(serviceType) ? this._container.Resolve(serviceType) : null; ???} ?? ???public IEnumerable<Object> GetServices(Type serviceType) { ??????return this._container.Registrations ?????????????.Where(reg => type.IsAssignableFrom(reg.RegisteredType)) ?????????????.Select(reg => string.IsNullOrEmpty(reg.Name) ? this._container.Resolve(type) : this._container.Resolve(type, reg.Name)); ???} ?? } |
使用 UnityDependencyResolver 的方法也很簡單, 只要在 Global.asax.cs 里添加下面一行代碼即可:
?| 1 | GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new UnityDependencyResolver(container)); |
將 UnityDependencyResolver 配置好之后, Web API 框架將會在運行時向其請求一系列的接口實現:
這些接口都是 Web API 公開的擴展點, 可以根據需要來對這些接口進行實現, 并通過 Unity 進行配置, 讓其注入到 Web API 運行時中。 接下來將逐個討論這些擴展點。
擴展
IHttpControllerFactory
IHttpControllerFactory 接口有兩個方法, 負責創建和銷毀 HttpController 實例:
- CreateController(HttpControllerContext, Type) : IHttpController
- ReleaseController(IHttpController) : void
這個接口的默認實現是 DefaultHttpControllerFactory , 根據當前請求的上下文通過創建 HttpControllerDescriptor , 然后通過 HttpControllerDescriptor 的 ControllerActivator 創建對應的 IHttpController 實例。
ILogger
只是一個日志接口, 有下面的幾個方法:
- Log(string, TraceLevel, Func) : void
- LogException(string, TraceLevel, Exception) : void
默認的實現是 DiagnosticLogger , 通過 ILSpy 觀察, 貌似什么都沒有做。
IHttpControllerActivator
負責創建具體的 Controller 實例, 只有一個方法:
- Create(HttpControllerContext, Type) : IHttpController
默認的實現是 DefaultHttpControllerActivator , 先向 DependencyResolver 請求對應 Controller 類型的實例, 如果返回為空, 則通過動態編譯包裝 Controller 類型構造函數的 lambda 表達式進行創建實例, 相關的代碼如下:
?| 1 2 3 4 | Func<IHttpController> func = TypeActivator.Create<IHttpController>(controllerType); Tuple<HttpControllerDescriptor, Func<IHttpController>> value = Tuple.Create<HttpControllerDescriptor, Func<IHttpController>>(controllerContext.ControllerDescriptor, func); Interlocked.CompareExchange<Tuple<HttpControllerDescriptor, Func<IHttpController>>>(ref this._fastCache, value, null); result = func(); |
IHttpActionSelector
負責選擇合適的動作, 默認的實現是 ApiControllerSelector , 選擇規則如下:
IHttpActionInvoker
負責調用 HttpActionSelector 選擇到的方法, 該接口有一個方法:
- InvokeActionAsync(HttpActionContext, CancellationToken) : Task<HttpResponseMessage>
默認的實現是 ApiControllerActionInvoker , 通過反射找出動作方法的參數信息, 然后再通過動態創建 lambda 表達式對方法進行調用, 取得返回結果, 部分代碼如下:
?| 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 | ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object[]), "parameters"); List<Expression> list = new List<Expression>(); ParameterInfo[] parameters = methodInfo.GetParameters(); for (int i = 0; i < parameters.Length; i++) { ???ParameterInfo parameterInfo = parameters[i]; ???BinaryExpression expression = Expression.ArrayIndex(parameterExpression2, Expression.Constant(i)); ???UnaryExpression item = Expression.Convert(expression, parameterInfo.ParameterType); ???list.Add(item); } UnaryExpression instance2 = (!methodInfo.IsStatic) ? Expression.Convert(parameterExpression, methodInfo.ReflectedType) : null; MethodCallExpression methodCallExpression = Expression.Call(instance2, methodInfo, list); if (methodCallExpression.Type == typeof(void)) { ???Expression<Action<object, object[]>> expression2 = Expression.Lambda<Action<object, object[]>>(methodCallExpression, new ParameterExpression[] ???{ ??????parameterExpression, ??????parameterExpression2 ???}); ???Action<object, object[]> voidExecutor = expression2.Compile(); ???return delegate(object instance, object[] methodParameters) ???{ ??????voidExecutor(instance, methodParameters); ??????return null; ???} ???; } UnaryExpression body = Expression.Convert(methodCallExpression, typeof(object)); Expression<Func<object, object[], object>> expression3 = Expression.Lambda<Func<object, object[], object>>(body, new ParameterExpression[] { ???parameterExpression, ???parameterExpression2 }); return expression3.Compile(); |
取得返回結果之后, 再調用 ApiResponseConverter 的 GetResponseConverter 方法找到合適的 Converter , 最后返回 Task<HttpResponseMessage>
IFilterProvider
負責提供過濾的標記, Web API 框架內置了下面的幾個 FilterProvider :
- EnumerableEvaluatorFilterProvider 負責提供對 IENumerable 的每個元素的轉換的標記, 簡單的說, 就是負責提供將 Action 方法返回的 IEnumerable 的結果進行自定義轉換的標記;
- QueryCompositionFilterProvider 負責對 Action 方法返回的 IQueryable 的結果進行符合 OData 約定的 URL 參數進行再次過濾的標記 QueryCompositionFilterAttribute , 目前只支持 $filter 、 $orderby 、 $skip 以及 $top ;
- ActionDescriptorFilterProvider
- ConfigurationFilterProvider
注意, 這里說的是 FilterProvider, 不是 Filter , 也不是 FilterAttribute 。
IActionValueBinder
負責綁定 Action 方法的參數, 默認的實現是 DefaultActionValuebinder , 通過調用 ValueProviderFactory 、 ModelBinderProvider 進行參數綁定, 支持多種形式的參數綁定, 綁定策略比較復雜, 總的來說是簡單的參數從 URL 中綁定, 復雜參數從 HTTP 請求內容中獲取。
ValueProviderFactory
定義了 Action 參數從哪里獲取, 有以下幾個實現, 分別支持從 URI 、 QueryString、 Post 內容中提取參數值:
- CompositeValueProviderFactory
- KeyValueModelProviderFactory
- RouteDataValueProviderFactory
- QueryStringValueProviderFactory
ModelBinderProvider
定義了如何將獲取到的 HTTP 請求的的參數之綁定到指定的參數。 System.Web.Http.ModelBinding.Binders 命名空間內提供了多種 BinderProvider , 應該可以處理大多數常見的類型。
ModelMetadataProvider
負責提供模型元數據描述信息。
ModelValidatorProvider
負責根據元素據信息對模型進行驗證。
IFormatterSelector
負責選擇合適的格式, 包括客戶端請求的格式以及服務端返回的格式, 默認實現是 FormatterSelector , 能夠提下面的 MediaFormater :
- BufferedmediaTypeFormatter 提供對二進制格式的讀取與寫入;
- FormUrlEncodedMediaTypeFormatter 提供對表單 URL 編碼格式的讀取與寫入;
- JsonMediaTypeFormatter 提供對 Json 格式的讀取與寫入;
- XmlMediaFormatter 提供對 XML 格式的讀取與寫入。
轉載自:http://www.cnblogs.com/beginor/archive/2012/03/22/2411496.html
轉載于:https://www.cnblogs.com/kericai/archive/2013/01/12/2857811.html
總結
以上是生活随笔為你收集整理的MVC核心功能组件和简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jsfl学习
- 下一篇: CentOS下firefox安装flas