2014-05-22 99 views
3

50,000ft概述:Web API中的請求依賴關係解決方案

IIS託管的Web API(OWIN)。

在OWIN中間件中,我做了一堆事情(API密鑰驗證以驗證請求,創建原則等)。

我使用Unity作爲我的容器。一旦我真的到達我的控制器,我正在注入一個服務類,它從我的控制器中抽象出我的存儲庫。在服務層,我執行諸如審計跟蹤,歷史記錄等等,以便在我注入服務類的任何地方都可以獲得額外的好處。

這一切工作,生活是美好的,yada yada yada。

直到...

我有一個自定義首部的值(X-OnBehalfOf),其API的呼叫者與特定請求正在被執行的用戶ID填充。這是應用程序的一個要求,其實現非常簡單。

我可以從任何有權訪問請求的地方(OWIN中間件,控制器等等)輕鬆地檢索到這個值。然而,我試圖解決的問題是在嘗試在服務層中獲取該值時出現的。

因爲我使用我的容器來解析服務類的實例,所以我最初的解決方案是實現類似IHeaderProvider的東西,並將其注入到服務類的構造函數中,但我似乎無法弄清楚如何獲得對該類中的請求的引用,因爲它不在管道中。

我相信有一個明顯的方法可以做到這一點,但我一直在遇到問題。有沒有人知道如何得到這個參考,而不必新增它,這樣我就可以利用我的DI容器爲我完成這項工作?

回答

4

看來我只是需要把它放在紙上。這是我如何解決它:

集裝箱:

 container.RegisterType<IHeaderProvider, HeaderProvider>(new HierarchicalLifetimeManager()); 
     container.RegisterType<HttpContextBase>(new InjectionFactory(c => new HttpContextWrapper(HttpContext.Current))); 

IHeaderProvider:

public interface IHeaderProvider 
{ 
    Guid GetOnBehalfOf(); 
} 

HeaderProvider:

public class HeaderProvider : IHeaderProvider 
{ 
    private readonly HttpContextBase _httpContextBase; 

    public HeaderProvider(HttpContextBase httpContextBase) 
    { 
     _httpContextBase = httpContextBase; 
    } 

    public Guid GetOnBehalfOf() 
    { 
     var xOnBehalfOf = _httpContextBase.Request.Headers.Get("X-OnBehalfOfId"); 
     Guid userId; 

     if (string.IsNullOrWhiteSpace(xOnBehalfOf)) 
      throw new Exception("Missing user ID"); 

     if (Guid.TryParse(xOnBehalfOf, out userId)) 
     { 
      return userId; 
     } 

     throw new Exception("Invalid user ID"); 
    } 
} 
+0

這是一個很好的解決方案!您應該將其標記爲答案。 –

+0

謝謝!我經常不把自己的發現標記爲答案,因爲它感覺很奇怪:)。希望它有幫助。 –

+1

[HierarchicalLifetimeManager](https://msdn.microsoft.com/en-us/library/ff660872(v = pandp.20).aspx)不是我認爲的正確的終生選項。我建議使用PerResolveLifetimeManager。 –

相關問題