sobota, 25 września 2010

HttpContext - Problemy i implementacja wrappera.

Witam dziś podczas kodowania natrafiłem na dosyć nieprzyjemne utrudnienie. Mianowicie dotyczy ono wstrzykiwania poprzez IoC HttpContext i pobierania aktualnego kontekstu do klas które tego potrzebują np. sesja. ciasteczka itp. Jak wiadomo HttpContext jest trudno dostępnym obiektem i ciężko w łatwy sposób wstrzyknąć. Wiec postanowiłem napisac wrapper do HttpContext.

HttpContextProvider
Nasz obiekt będzie dziedziczył po klasie IHttpContextProvider. Będzie on posiadał podstawowe zmienna które pozwolą nam na dostanie się do wszystkich parametrów aktualnego HttpContextu. Obiekt bedzie wyglądał tak:
public class HttpContextProvider : IHttpContextProvider
{

    public System.Web.HttpContextBase Context
    {
        get { return new HttpContextWrapper(HttpContext.Current); }
    }

    public System.Web.HttpRequestBase Request
    {
        get { return Context.Request; }
    }

    public System.Web.HttpResponseBase Response
    {
        get { return Context.Response; }
    }

    public System.Collections.Specialized.NameValueCollection FormOrQueryString
    {
        get
        {
            if (Request.RequestType == "POST")
            {
                return Request.Form;
            }
            return Request.QueryString;
        }
    }
}
Generalnie nic specjalnie trudnego dziwnego w tym obiekcie. Jedyny co może wzbudzić ciekawość to tajemniczy klasa HttpContextWrapper z biblioteki System.Web. Ta klasa dziedziczy po HttpContextBase i pozwala na dostanie się do funkcjonalności aktualnego kontekstu. Dzięki takiemu rozwiązaniu mamy łatwy dostęp do HttpContextu z kontenera IoC jak i również ułatwia nam to testy ponieważ jak większość z was wie stworzenie fałszywego kontekstu jest dosyć nieprzyjemnym zadaniem.

Session Manager
Wszystkie powyższe wypociny były związane z tym ze chciałem stworzyć obiekt do zarządzania sesją użytkownika. Główne rozwiązanie które chciałem dodać silnie typowana obsługa sesji. Klasa sessionManagera wygląda tak:
public class SessionManager : ISessionManager
{
    private IHttpContextProvider _httpContextProvider;

    public SessionManager(IHttpContextProvider provider)
    {
        _httpContextProvider = provider;
    }

    public void Set<T>(string name, T value)
    {
        _httpContextProvider.Context.Session.Add(name, value);
    }

    public T Get<T>(string name)
    {
        return (T)_httpContextProvider.Context.Session[name];
    }

    public T TryGet<T>(string name)
    {
        try
        {
            return (T)_httpContextProvider.Context.Session[name];
        }
        catch (NullReferenceException e)
        {
            return default(T);
        }
    }

    public void Abandon()
    {
        _httpContextProvider.Context.Session.Abandon();
    }
}
Klasa posiada metody podstawowe do pobierania i ustawiania wartości w sesji jak i również porzucania sesji. Oprócz tego dodałem metodę TryGet która pobiera wartość z sesji natomiast gdy nie istnieje to zwraca standardową wartość dla danego typu. Podczas zwykłego pobierania metoda Get wyrzuci wyjątek NullReferenceException co czasami jest niepożądane. Jest to coś podobnego jak mamy w słowniku. Natomiast niestety kolekcja sesji nie jest słownikiem. To tyle na dziś.

Brak komentarzy:

Prześlij komentarz