开发者

Abstracting HttpContext Request and Session - thread safety

I have the following assemblies in my ASP.NET app:

Website - this is an ASP.NET website ClassLib - this is just a class lib that contains all the business logic

Class Lib needs to interact with the HttpContext Session and Request objects. This is a code upgrade from an old ASP app, where I've hoovered all the VBScript that contained the logic and put it into VB.NET. We simply didn't have time to rewrite.

Instead of ClassLib interacting directly with HttpContext, which I thought was BAD and also prevented us from unit testing, I introduced the following abstraction layer:

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

etc.

This means in the unit tests I can supply my own MockRequest object into this Request class, which is just a simple NameValue collection. The code in the ClassLib and the Website then simply use the Request class and are none the wiser that it isn't coming from the HttpContext, but rather this mock class.

When it comes to the real deal, I simply have the following (C#) class:

public class RealRequest : IRequestWrapper
    {
        public void Initialize(HttpContext context)
        {
        }

        #region Implementation of IRequestWrapper

        public object GetVal(string index)
        {
            return HttpContext.Current.Request[index];
        }

etc.

This is initialised in Session_Start of global.asax in the Website, as follows:

 protected void Session_Start(object sender, EventArgs e)
    {


        IRequestWrapper requestWrapper = new RealRequest();
        WebSession.Request.InitRequest(ref requestWrapper);
  开发者_如何学C  }

I think this is similar to the Static Gateway pattern.

Now, I am aware of singletons and static vars in a multi threaded environment such as ASP.NET, but this is slightly different. When it gets down to the RequestWrapper.GetVal(), its actually going to the HttpContext for that running thread - and pulling the value from that.

Certainly, any concurrent tests that we do with multiple users hitting the same server have never shown up any strange behaviour.

I'm just looking for re-assurance that this is a sound design, and if not why not?

Thanks Duncan


This is fine. We have a very similar case in our applications that either uses HttpContext if it exists or fake implementations otherwise.

The one thing to watch out for is that there is a very specific instance where HttpContext.Current will return a value but HttpContext.Current.Request will throw an exception when triggered by the Application_Start event. In framework code, you really don't know (or want to know) what triggered the call though.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜