使用 ASP.NET Web API 2.1 配置依賴注入
我正在創建一個 ASP.NET Web API 2.1 站點,並且因為我想將依賴項直接注入控制器,所以我創建了自己的 IDependencyResolver 實現,以便 StructureMap 為我處理。
public class StructureMapDependencyResolver : IDependencyResolver { public IDependencyScope BeginScope() { return this; } public object GetService(Type serviceType) { return ObjectFactory.GetInstance(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return ObjectFactory.GetAllInstances(serviceType).Cast<object>(); } public void Dispose() { } }然後,我通過將此行添加到 Global.asax 中的 Application_Start 方法來告訴 Web API 使用此類
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver();那已編譯但是當我嘗試在瀏覽器中訪問任何 API 方法時,我收到了這樣的錯誤
No Default Instance defined for PluginFamily System.Web.Http.Hosting.IHostBufferPolicySelector, System.Web.Http這個問題相對容易解決,因為我在 StructureMap 配置中添加了一行
this.For<IHostBufferPolicySelector>().Use<WebHostBufferPolicySelector>();但是,後來我遇到了其他 System.Web.Http 類的其他類似錯誤,雖然我可以解決其中的一些錯誤,但我仍然堅持如何處理其中的 3 個,即 ITraceManager、IExceptionHandler 和 IContentNegotiator。
問題是 TraceManager 似乎是 ITraceManager 的預設實現是一個內部類,所以我不能在我的 StructureMap 配置中引用它。
那麼我是完全錯誤地解決這個問題,還是有其他方法可以注入這些內部類?
我想給你一個建議和解釋為什麼不走這條路,以及如何以不同的方式做(我什至會說更好更正確)。
IDependencyResolver可以在此處找到不適當設計的完整和完整解釋: Mark Seemann的 ASP.NET Web API 的依賴注入和生命週期管理讓我引用這些重要部分:
IDependencyResolver 的問題
主要問題
IDependencyResolver是它本質上是一個Service Locator。Service Locator 反模式存在許多問題,但其中大部分問題我已經在本部落格的其他地方(以及我的書中)進行了描述。Service Locator 的一個缺點我還沒有寫太多,那就是每次呼叫 GetService 時根本沒有上下文。這是服務定位器反模式的普遍問題,而不僅僅是 IDependencyResolver。並且:
…依賴關係圖需要了解有關上下文的資訊。請求的 URL 是什麼?請求的基地址(主機名等)是什麼?如何在單個請求中共享依賴實例?要回答此類問題,您必須了解上下文,而 IDependencyResolver 不提供此資訊。
簡而言之,
IDependencyResolver這不是構成依賴圖的正確方法。幸運的是,ASP.NET Web API 有一個更好的擴展點來實現這個目的。服務啟動器
因此,這種情況下的答案將是
ServiceActivator. 請看一下這個答案:的一個例子
ServiceActivator:public class ServiceActivator : IHttpControllerActivator { public ServiceActivator(HttpConfiguration configuration) {} public IHttpController Create(HttpRequestMessage request , HttpControllerDescriptor controllerDescriptor, Type controllerType) { var controller = ObjectFactory.GetInstance(controllerType) as IHttpController; return controller; } }我們可以用 StructureMap 做的所有事情都已經到位。Web API 框架的關鍵特性仍然存在……我們不必破解它們。我們也寧願使用 DI/IoC 然後服務定位器