2010-12-01 2 views
1

Я следующие узлы в моем приложении ASP.NET:Абстрагируясь HttpContext Запрос и Session - ниточный

Сайт - это веб-сайт ASP.NET ClassLib - это просто класс Lib, который содержит все бизнес логика

Класс Lib должен взаимодействовать с объектами сеанса HttpContext и Request. Это обновление кода из старого 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]; 
     } 

т.д.

Это инициализируется в session_start из global.asax на Веб-сайте, следующим образом :

protected void Session_Start(object sender, EventArgs e) 
    { 


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

Я думаю, что это похоже на шаблон статического шлюза.

Теперь я знаю одиночные и статические vars в многопоточной среде, такой как 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?

Смежные вопросы