Asp.net

使用 ASP.NET Web API 2.1 配置依賴注入

  • February 20, 2014

我正在創建一個 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 LocatorService 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 然後服務定位器

引用自:https://stackoverflow.com/questions/21919753