Dot-Net

簡單註入器:如何注入 HttpContext?

  • April 24, 2017

我已經開始使用 Simple Injector 作為我的 DI 容器(主要是出於性能原因:如果有人有建議,請告訴我)但是我編寫的一些類使用 HttpContextBase 作為建構子參數。我已經解決了現在從建構子中刪除它並創建一個屬性,如下所示:

   public HttpContextBase HttpContext
   {
       get
       {
           if (null == _httpContext)
               _httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
           return _httpContext;
       }
       set
       {
           _httpContext = value;
       }
   }

但我不喜歡這個解決方案……有什麼建議嗎?

您應該始終支持建構子注入而不是其他任何東西。這幾乎總是可能的。您可以按以下方式註冊您HttpContextBase的:

container.Register<HttpContextBase>(() =>
   new HttpContextWrapper(HttpContext.Current), 
   Lifestyle.Scoped);

這在呼叫 時可能會導致問題Verify(),因為在應用程序啟動期間HttpContext.Currentnull,並且HttpContextWrapper不允許將 null 傳遞給建構子。

嘗試保持您的配置可驗證總是好的,您可以將該註冊更改為以下內容:

container.Register<HttpContextBase>(() =>
{
   var context = HttpContext.Current;
   if (context == null && container.IsVerifying) return new FakeHttpContext();
   return new HttpContextWrapper(context);
},
   Lifestyle.Scoped);

FakeHttpContext是一個空HttpContextBase實現,以防止null在容器正在驗證時返回。FakeHttpContext就是這樣:

public class FakeHttpContext : HttpContextBase { }

但是請注意 HttpContext 是執行時數據,在構造過程中將執行時數據注入組件是一種反模式。與其將 HttpContext 或其上的任何抽象注入到您的組件中,不如創建一個特定於應用程序的抽象,為消費者提供其實際需要的內容(例如使用者身份或租戶 ID)。這種抽象的實現可以簡單地在內部呼叫 HttpContext.Current ,這完全避免了注入 HttpContext 的需要。

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