2010-12-01 81 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?