我在我的ASP.NET應用程序以下組件:抽象HttpContext的請求和會話 - 線程安全
網站 - 這是一個ASP.NET網站 CLASSLIB - 這只是一個IIb類包含所有業務邏輯
類Lib需要與HttpContext會話和請求對象進行交互。這是從一箇舊的ASP應用程序代碼升級,我已經將所有包含邏輯的VBScript提交到VB.NET中。我們根本沒有時間重寫。
相反CLASSLIB直接與HttpContext的相互作用,我認爲是BAD,並且還妨礙了我們的單元測試,我介紹了下列抽象層:
Public Class Request
Private Shared _requestWrapper as IRequestWrapper
Public Shared ReadOnly Property RequestWrapper()
Get
If _requestWrapper Is Nothing Then
Throw New Exception("_requestWrapper is null. Make sure InitRequest() is called with valid parameters")
End If
Return _requestWrapper
End Get
End Property
Public Shared Sub InitRequest(ByRef requestWrapper As IRequestWrapper)
_requestWrapper = requestWrapper
End Sub
Public Shared Function GetVal(ByVal key As String) As Object
Return RequestWrapper.GetVal(key)
End Function
等
這意味着在單元測試我可以將自己的MockRequest對象提供給這個Request類,它只是一個簡單的NameValue集合。 ClassLib和網站中的代碼然後簡單地使用Request類,而不是來自HttpContext的更明智的,而是這個模擬類。
當涉及到真正的交易,我只是有下列(C#)類:
public class RealRequest : IRequestWrapper
{
public void Initialize(HttpContext context)
{
}
#region Implementation of IRequestWrapper
public object GetVal(string index)
{
return HttpContext.Current.Request[index];
}
等
這是在網站中初始化的Global.asax在session_start的,如下:
protected void Session_Start(object sender, EventArgs e)
{
IRequestWrapper requestWrapper = new RealRequest();
WebSession.Request.InitRequest(ref requestWrapper);
}
我認爲這與靜態網關模式類似。
現在,我意識到多線程環境(如ASP.NET)中的單例和靜態變量,但這略有不同。當它到達RequestWrapper.GetVal()時,它實際上會轉到該運行線程的HttpContext - 並從中提取值。
當然,我們用多個用戶訪問同一臺服務器的任何併發測試都沒有顯示出任何奇怪的行爲。
我只是想再次確定這是一個完美的設計,如果不是爲什麼呢?
感謝 鄧肯