2010-06-18 9 views
6

Napisałem następujące metody rozszerzenia sesji, aby móc kontynuować i pobierać obiekty według ich typu. To działa dobrze dla mojego rozwiązania, ale musiałem skopiować moje metody rozszerzeń, aby pokryć stare HttpSessionState i nową HttpSessionStateBase. Chciałbym znaleźć sposób, aby przywrócić je do jednego zestawu, który obejmuje oba typy. jakieś pomysły?Jak mogę pisać rozszerzenia dla sesji bez konieczności pisania osobnych metod dla HttpSessionState i HttpSessionStateBase?

public static class SessionExtensions 
{ 
    #region HttpSessionStateBase 

    public static T Get<T>(this HttpSessionStateBase session) 
    { 
     return session.Get<T>(typeof(T).Name); 
    } 

    public static T Get<T>(this HttpSessionStateBase session, string key) 
    { 
     var obj = session[key]; 

     if(obj == null || typeof(T).IsAssignableFrom(obj.GetType())) 
      return (T) obj; 

     throw new Exception("Type '" + typeof(T).Name + "' doesn't match the type of the object retreived ('" + obj.GetType().Name + "')."); 
    } 

    public static void Put<T>(this HttpSessionStateBase session, T obj, string key) 
    { 
     session[key] = obj; 
    } 

    public static void Put<T>(this HttpSessionStateBase session, T obj) 
    { 
     session.Put(obj, typeof(T).Name); 
    } 

    #endregion 

    #region HttpSessionState 

    public static T Get<T>(this HttpSessionState session) 
    { 
     return session.Get<T>(typeof(T).Name); 
    } 

    public static T Get<T>(this HttpSessionState session, string key) 
    { 
     var obj = session[ key ]; 

     if(obj == null || typeof(T).IsAssignableFrom(obj.GetType())) 
      return (T) obj; 

     throw new Exception("Type '" + typeof(T).Name + "' doesn't match the type of the object retreived ('" + obj.GetType().Name + "')."); 
    } 

    public static void Put<T>(this HttpSessionState session, T obj) 
    { 
     session.Put(obj, typeof(T).Name); 
    } 

    public static void Put<T>(this HttpSessionState session, T obj, string key) 
    { 
     session[ key ] = obj; 
    } 

    #endregion 
} 

Odpowiedz

2

Znalazłem odpowiedź, która działa, ale są pewne wady. Mam nadzieję, że ktoś będzie mógł to ulepszyć.

@Andrew Hare powiedział, że nie należy implementować wspólnej bazy lub interfejsu. Właściwie tak. Oba implementują IEnumerable i ICollection. Nasuwa się pytanie, czy z tymi informacjami chcesz stworzyć metody rozszerzające, które rozszerzają IEnumerable lub ICollection, które są naprawdę przeznaczone tylko dla sesji? Może, może nie. W każdym razie, tutaj jest sposób, aby usunąć powielania metod rozszerzenie, które rozciągają HttpSessionState i HttpSessionStateBase jednocześnie:

public static class SessionExtensions 
{ 
    public static T Get<T>(this ICollection collection) 
    { 
     return collection.Get<T>(typeof(T).Name); 
    } 

    public static T Get<T>(this ICollection collection, string key) 
    { 
     object obj = null; 
     dynamic session = collection as HttpSessionState ?? (dynamic) (collection as HttpSessionStateBase); 

     if(session != null) 
     { 
      obj = session[key]; 

      if (obj != null && !typeof (T).IsAssignableFrom(obj.GetType())) 
       throw new Exception("Type '" + typeof (T).Name + "' doesn't match the type of the object retreived ('" + obj.GetType().Name + "')."); 
     } 

     return (T)obj; 
    } 

    public static void Put<T>(this ICollection collection, T obj) 
    { 
     collection.Put(obj, typeof(T).Name); 
    } 

    public static void Put<T>(this ICollection collection, T obj, string key) 
    { 
     dynamic session = collection as HttpSessionState ?? (dynamic) (collection as HttpSessionStateBase); 
     if(session!=null) 
      session[ key ] = obj; 
    } 
} 

ja nie szaleję tego rozwiązania, ale czuje się jak krok, przynajmniej w ciekawym kierunek.

1

Niestety żaden z tych typów nie ma wspólnej klasy bazowej ani interfejsu, z którego można korzystać - na razie trzeba będzie skopiować metody rozszerzenia.

3

Można zachować swój początkowy wdrażania i stosowania HttpSessionStateWrapper obsłużyć HttpSessionState sprawy:

SomeType t = new HttpSessionStateWrapper(SomeHttpSessionStateInstance) 
    .Get<SomeType>(); 
Powiązane problemy