ASP.NET MVC 會話 vs 全域 vs 記憶體
我有一個用 vanilla ASP.NET 編寫的應用程序,我想將它移植到 ASP.NET MVC。
然而,我對持久化對象的正確位置感到困惑。我需要堅持有幾個原因:
- 我希望所有人都有一個單一的數據庫連接,包裝在“儲存庫”或“管理器”樣式的對像中。
- 每個使用者都有一個使用者對象,需要在每個會話的基礎上保存。
通常,我會說#1 將被保存為 Globals.asax 中的靜態項目,可以使用
Global.Repository或類似方法命中。我通常會說#2 應該是在頁面的基類中某處具有會話支持儲存的屬性。
現在我感到困惑的原因是我聽說 MVC 中的會話發生了變化,並且 Global.asax 不再擁有相同的類。此外,頁面的概念已被刪除,因此向控制器的基類添加屬性似乎……錯誤。
怎麼說呢?
您的數據庫將進入您的控制器的基類。這個基類應該擴展 Controller,你所有的控制器都應該擴展基類。這是一個小例子:
public class BaseController : Controller { private AuthServices _auth; private LogHelper _log; private Repository _repository; /// <summary> /// <see cref="AuthServices"/> /// </summary> protected AuthServices Authorization { get { return _auth ?? (_auth = new AuthServices()); } } /// <summary> /// <see cref="LogHelper"/> /// </summary> protected LogHelper Log { get { return _log ?? (_log = new LogHelper()); } } /// <summary> /// <see cref="Repository"/> /// </summary> protected Repository Repository { get { return _repository ?? (_repository = new Repository()); } } }注意惰性實例化。這使我可以在執行測試之前潛入並使用模擬設置我的私有欄位。
至於會話,您的使用者對象仍然可以保存在會話中,就像在傳統的 ASP.NET 應用程序中一樣。幾乎所有東西都還在(響應、記憶體、會話等),但其中一些已經用 System.Web.Abstractions 中的類進行了包裝,以便可以模擬它們進行測試。它們的行為方式仍然相同,儘管您不應該在它們的傳統角色中使用它們中的一些(例如,不要 Response.Redirect,返回一個 ActionResult,例如執行重定向的 RedirectToRouteResult)。
至於你的問題背後的推理……
不要強調單個數據庫連接。根據您的實施,這甚至可能不是一個好主意,因為請求可能會相互影響。只需打開您的連接,使用它,並在完成後處理/關閉它。
此外,MVC 帶來的最大變化之一是拒絕了傳統 ASP.NET 試圖為 Web 開髮帶來的有狀態模型。所有這些框架和視圖狀態都不再存在(不要注意幕後的人)。您持有的狀態越少,您的 Web 應用程序就越不復雜且越健壯。試試看,你可能會喜歡。