我在我的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 - 并从中提取值。
当然,我们用多个用户访问同一台服务器的任何并发测试都没有显示出任何奇怪的行为。
我只是想再次确定这是一个完美的设计,如果不是为什么呢?
感谢 邓肯