2010-12-01 23 views
1

Je les assemblées suivantes dans mon application ASP.NET:Abstracting HttpContext Demande et session - sécurité fil

site - c'est un site Web ASP.NET ClassLib - c'est juste une classe lib qui contient toutes les activités logique

La classe Lib doit interagir avec les objets HttpContext Session et Request. Il s'agit d'une mise à niveau de code à partir d'une ancienne application ASP, dans laquelle j'ai placé tous les scripts VBScript contenant la logique et les avez placés dans VB.NET. Nous n'avons tout simplement pas eu le temps de réécrire.

Au lieu de ClassLib interagir directement avec HttpContext, que je pensais était mauvais et aussi nous a empêchés de tests unitaires, j'introduit la couche d'abstraction suivante:

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.

Cela signifie dans l'unité tests Je peux fournir mon propre objet MockRequest dans cette classe Request, qui est juste une simple collection NameValue. Le code dans ClassLib et le site Web utilisent simplement la classe Request et ne sont pas plus sages que cela ne vient pas du HttpContext, mais plutôt de cette classe fictive.

En ce qui concerne la vraie affaire, j'ai simplement ce qui suit (C#) Classe:

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

     #region Implementation of IRequestWrapper 

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

etc.

Ceci est initialisés dans Session_Start de global.asax dans le site Web, comme suit :

protected void Session_Start(object sender, EventArgs e) 
    { 


     IRequestWrapper requestWrapper = new RealRequest(); 
     WebSession.Request.InitRequest(ref requestWrapper); 
    } 

Je pense que cela est similaire au modèle de passerelle statique. Maintenant, je suis conscient des singletons et des variables statiques dans un environnement multithread comme ASP.NET, mais c'est légèrement différent. Quand il descend à RequestWrapper.GetVal(), il va en fait à la HttpContext pour ce thread en cours d'exécution - et en tirant la valeur de cela. De toute évidence, tous les tests simultanés que nous faisons avec plusieurs utilisateurs frappant le même serveur n'ont jamais révélé de comportement étrange.

Je suis juste à la recherche de re-assurance que c'est une conception sonore, et sinon pourquoi pas?

Merci Duncan

Répondre

1

C'est très bien. Nous avons un cas très similaire dans nos applications qui utilise HttpContext s'il existe ou de fausses implémentations dans le cas contraire.

La seule chose à surveiller est qu'il existe une instance très spécifique où HttpContext.Current renverra une valeur mais HttpContext.Current.Request lèvera une exception lorsqu'il sera déclenché par l'événement Application_Start. Dans le code cadre, vous ne savez pas (ou ne voulez pas savoir) ce qui a déclenché l'appel.

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