Передача веб-контекста в «сервис» в приложении ASP MVC - PullRequest
5 голосов
/ 02 декабря 2008

Я пытаюсь найти способ передачи текущего веб-контекста http классу обслуживания (или инициализации класса со ссылкой на него). Я делаю это, чтобы абстрагировать остальную часть приложения от необходимости знать что-либо о контексте http.

Я также хочу, чтобы сервис тестировался с использованием TDD, возможно, с использованием одной из структур Mockable. Следовательно, было бы предпочтительнее использовать интерфейс, а не реальный класс.

Пример того, чего я хотел бы достичь:

class WebInstanceService 
{
    private IHttpContext _Context;        

    public WebInstanceService( ... , IHttpContext HttpContext )
    {
        ....
        _Context = HttpContext;
    }

    // Methods...
    public string GetInstanceVariable(string VariableName)
    {
         return _Context.Current.Session[VariableName];
    }
}

Одна из основных проблем, с которыми я столкнулся, заключается в том, что IHttpContext не существует, http-контекст .net является подклассом абстрактного класса, который не может быть смоделирован (легко?).

Другая проблема заключается в том, что я не могу инициализировать глобальные экземпляры класса, так как тогда контекст не будет релевантным для большинства запросов.

Я мог бы сделать класс статичным и потребовать передачи контекста каждой функции, как она называется, т.е. 1012 *

public static string GetInstanceVariable(string VariableName, HttpContext Context) 
{ ... }

но это не облегчает тестирование класса, мне все еще нужно создать HttpContext и, кроме того, любые не поддерживающие веб-сервисы службы, которые хотят использовать этот класс, внезапно должны иметь возможность извлекать контекст, требующий от них быть тесно связанным с веб-сервером - вот и вся причина создания этого класса.

Я открыт для ВСЕХ предложений, особенно тех, которые, как известно, облегчают тестирование на tdd. Как бы люди предложили мне заняться этой проблемой?

Приветствия

Ответы [ 3 ]

3 голосов
/ 02 декабря 2008

Именно поэтому были представлены HttpContextBase и HttpContextWrapper. Вы, вероятно, хотите использовать HttpContextBase, а при передаче реального контекста использовать new HttpContextWrapper( httpContext ), хотя я думаю, что то, что доступно вам в контроллере, уже имеет тип HttpContextBase. Я бы каждый раз создавал один из них в своем контроллере, а не пытался ссылаться на текущий контекст из статического глобального экземпляра HttpContext.Current. Если вам это нужно в вашем представлении, передайте ссылку на ваш строго типизированный контекст в ViewData.

Я часто копирую HttpContextBase в своих тестах.

class WebInstanceService 
{
    private HttpContextBase _Context;        

    public WebInstanceService( ... , HttpContextBase HttpContext )
    {
        ....
        _Context = HttpContext;
    }

    // Methods...
    public string GetInstanceVariable(string VariableName)
    {
         return _Context.Session[VariableName];
    }
}
1 голос
/ 02 декабря 2008

ASP.NET поставляется с System.Web.Abstractions, которые включают HttpContextBase, который можно использовать для работы с HttpContext в ситуации тестирования.

Я бы лично абстрагировал прямую зависимость от HttpContext.

1 голос
/ 02 декабря 2008

То, что мы делаем, это раскручиваем одну из них http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx

Легко, как пирог, просто создайте экземпляр HttpSimulator и введите значения, и HttpContext.Current будет заполнен всем, что вы укажете.

IHttpContext - это то, что находится в MVC, и, по-видимому, однажды будет в веб-формах. Надеюсь, что этот день будет .net 4

...