在前文的Demo中,webApi的Controller是不能自動注入的,原因是 IHttpController 和 IController 是通過兩個不同的途徑進行激活的。
IHttpController的激活是通過 IHttpControllerActivator 接口完成的
// 摘要: // 定義 System.Web.Http.Dispatcher.IHttpControllerActivator 所需的方法。 public interface IHttpControllerActivator { // 摘要: // 創建一個 System.Web.Http.Controllers.IHttpController 對象。 // // 參數: // request: // 消息請求。 // // controllerDescriptor: // HTTP 控制器描述符。 // // controllerType: // 控制器的類型。 // // 返回結果: // System.Web.Http.Controllers.IHttpController 對象。 IHttpController Create(HttPRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType); }
而其默認實現類為:DefaultHttpControllerActivator
// 摘要: // 表示 System.Web.Http.Dispatcher.IHttpControllerActivator 的默認實現??梢酝ㄟ^ System.Web.Http.Services.DependencyResolver // 注冊不同的實現。我們已針對每個 System.Web.Http.Controllers.HttpControllerDescriptor 實例具有一個 // System.Web.Http.Controllers.ApiControllerActionInvoker 實例的情況進行優化,但也支持一個 System.Web.Http.Controllers.ApiControllerActionInvoker // 具有多個 System.Web.Http.Controllers.HttpControllerDescriptor 實例的情況。對于后一種情況,查找會略慢一些,因為查找需要遍歷 // HttpControllerDescriptor.Properties 目錄。 public class DefaultHttpControllerActivator : IHttpControllerActivator { // 摘要: // 初始化 System.Web.Http.Dispatcher.DefaultHttpControllerActivator 類的新實例。 public DefaultHttpControllerActivator(); // 摘要: // 使用給定 request 創建 controllerType 所指定的 System.Web.Http.Controllers.IHttpController。 // // 參數: // request: // 請求消息。 // // controllerDescriptor: // 控制器描述符。 // // controllerType: // 控制器的類型。 // // 返回結果: // 類型 controllerType 的實例。 public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType); }
知道了上述信息,最簡單的辦法就是繼承并重寫 DefaultHttpControllerActivator ,但是不巧的是其 Create 不是虛函數,不能重寫。咋辦法呢?變通一下,動態改變對象的行為——裝飾模式。當然這里沒必要嚴格按照裝飾模式死板的去應用,完全沒必要的。只需要按照裝飾原理,將 DefaultHttpControllerActivator 進行裝飾,再將裝飾對象注冊到系統中即可。
比如:
/// <summary> /// 用于Web Api /// </summary> private class MyHttpControllerActivator : IHttpControllerActivator { private DefaultHttpControllerActivator defaultActivator; public MyHttpControllerActivator() { this.defaultActivator = new DefaultHttpControllerActivator(); } public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) { IHttpController httpController = this.defaultActivator.Create(request, controllerDescriptor, controllerType); if (httpController != null) { /// 自動裝配屬性 /// <para>為屬性對象啟用代理,并延遲初始化被代理的對象</para> DelayProxyUtil.AutowiredProperties(httpController); } return httpController; } }
然后在 應用程序啟動的時候進行注冊:
// 使AOP適應 WebApi GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new MyHttpControllerActivator());
如此,WebApi中的Controller屬性,也會被自動注入了。
源碼地址:http://files.VEVb.com/files/08shiyan/AOPDemo.zip
(暫完,后續補充中...)
新聞熱點
疑難解答