В моем приложении ASP.NET есть следующие сборки:
Веб-сайт - это веб-сайт ASP.NET
ClassLib - это просто библиотека классов, которая содержит всю бизнес-логику
Class Lib должен взаимодействовать с объектами HttpContext Session и Request. Это обновление кода из старого приложения ASP, где я собрал весь VBScript, содержащий логику, и поместил его в VB.NET. У нас просто не было времени переписать.
Вместо того, чтобы ClassLib напрямую взаимодействовал с HttpContext, который, как я думал, был ПЛОХОЙ, а также мешал нам проводить модульное тестирование, я ввел следующий уровень абстракции:
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);
}
Я думаю, что это похоже на шаблон Static Gateway.
Теперь мне известны синглтоны и статические переменные в многопоточной среде, такой как ASP.NET, но это немного отличается. Когда он переходит к RequestWrapper.GetVal (), он на самом деле идет к HttpContext для этого запущенного потока - и извлекает значение из этого.
Конечно, любые параллельные тесты, которые мы проводим с несколькими пользователями, подключающимися к одному и тому же серверу, никогда не обнаруживали какого-либо странного поведения.
Я просто хочу заверить, что это звуковой дизайн, и если нет, то почему?
Спасибо
Дункан