2010-12-01 37 views
1

我在我的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 - 並從中提取值。

當然,我們用多個用戶訪問同一臺服務器的任何併發測試都沒有顯示出任何奇怪的行爲。

我只是想再次確定這是一個完美的設計,如果不是爲什麼呢?

感謝 鄧肯

回答

1

這是好的。在我們的應用程序中,我們有一個非常相似的情況,如果它存在,則使用HttpContext,否則使用虛假實現。

有一點需要注意的是,有一個非常具體的例子,其中HttpContext.Current將返回一個值,但HttpContext.Current.Request將在由Application_Start事件觸發時引發異常。在框架代碼中,你真的不知道(或者想知道)觸發了什麼。

Workaround for HttpContext.HideRequestResponse being internal? Detect if HttpContext.Request is really available?