1

我正在ASP.NET MVC5中開發Web應用程序。如何在DI項目中使用會話提供程序

像所有基本的Web應用程序一樣,它也有一個登錄頁面供用戶進行身份驗證。一旦通過身份驗證,我想在會話中存儲一些與用戶相關的項目,這樣我就不必每次都重新查詢數據庫以重新構建已通過身份驗證的用戶。

閱讀Mark Seemann的關於依賴注入的書後,我想鬆散地耦合所有層,並確保一切都可以輕鬆替換。

目前我的SessionProvider默認使用Session對象,但也許將來可能會改變爲另一種類型的存儲機制。

我採取的方法是使用周圍語境他與TimeProvider爲例進行了說明,但我想知道如果這是此功能正確的方法,如果它是線程安全的(也可用於單元測試)。

我的解決方案是否合適,或者如何實現這樣的機制?這一直在我頭上好幾天,所以誰能幫我定義最佳的解決方案?

謝謝!

public abstract class SessionProvider 
{ 
    private static SessionProvider _current; 

    static SessionProvider() 
    { 
     _current = new DefaultSessionProvider(); 
    } 

    public static SessionProvider Current 
    { 
     get { return _current; } 
     set 
     { 
      if (value == null) 
      { 
       throw new ArgumentNullException(); 
      } 
      _current = value; 
     } 
    } 

    public abstract string UserName { get; set; } 
} 

我的本地默認:

public class DefaultSessionProvider : SessionProvider 
{ 
    public override string UserName 
    { 
     get { return (string) HttpContext.Current.Session["username"]; } 
     set { HttpContext.Current.Session["username"] = value; } 
    } 
} 

所以,我在我的整個解決我SessionProvider訪問,這是否是一個真實的會話對象或數據庫驅動的存儲機制...

SessionProvider.Current.UserName = "myUserName"; 
+0

正如你可以在Mark Seemann的書中看到的那樣,Ambient Context很難找到正確的解決方案。我會說這不是正確的解決方案,直到另有證明。 – Steven

+0

是的,但是如果我不得不將它傳遞給每一項服務,它會污染API。它只用於查詢數據,而不是寫它。存在適當的本地缺省值(DefaultSessionProvider),並保證可用。 在某種程度上,會議本身可以被看作是一個環境背景以及我認爲... 你會建議什麼樣的解決方案來存儲和檢索會話數據? – Jules

+0

如果您需要「將其傳遞給每項服務」,則會遇到不同的問題。在這種情況下,你很可能在談論一個交叉問題。橫切關注點應與正常代碼分開,例如使用攔截,修飾或其他面向方面的編程技術。 – Steven

回答

0

一旦通過身份驗證,我想在 會話中存儲幾個用戶相關的項目,所以我不必查詢da tabase每次到 重建已認證的用戶。

好吧,它看起來像你正在研究某種緩存機制。它是否在會話或Redis緩存或任何其他類型的緩存中都無關緊要。這個緩存是鍵值存儲。我會創建緩存接口,類似這樣的:

interface ICache 
{ 
    object this[string key] {get; set;} 
} 

並創建具體的類。 SessionCache在你的情況下:

public SessionCache : ICache 
{ 
    private IHttpSessionState _session; 
    public SessionCache(IHttpSessionState session) 
    { 
     _session = session; 
    } 

    // ICache implementation goes here... 
} 

所以你會縮小問題的範圍,將Session對象依賴注入具體類(SessionCache)。使用Ninject,您可以執行如下操作:

.WithConstructorArgument("session",ninjectContext=>HttpContext.Session); 

之後您可以最終使您的控制器依賴於ICache。

在你的單元測試項目中,你可以創建另一個ICache具體類,就像DummyCache和內存中的緩存一樣。所以你可以測試你的控制器,而不必堅持Session對象。

相關問題