2010-06-18 11 views
6

Escribí los siguientes métodos de extensión para la Sesión para que pueda persistir y recuperar objetos por su tipo. Esto funciona bien para mi solución, pero terminé teniendo que duplicar mis métodos de extensión para cubrir el viejo HttpSessionState y el nuevo HttpSessionStateBase. Me gustaría encontrar una forma de volver a bajarlos a un conjunto que cubra ambos tipos. ¿Alguna idea?¿Cómo puedo escribir extensiones para Session sin tener que escribir métodos separados para HttpSessionState y 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 
} 

Respuesta

2

Encontré una respuesta que funciona pero que presenta algunos inconvenientes. Espero que alguien pueda mejorarlo.

@Andrew Hare dijo que ni implementar una base o interfaz común. Bueno, en realidad, lo hacen. Ambos implementan IEnumerable e ICollection. La pregunta es, con esa información a cuestas, ¿desea crear métodos de extensión que extiendan IEnumerable o ICollection que solo están destinados a la Sesión? Tal vez tal vez no. En cualquier caso, aquí hay una manera de eliminar la duplicación con los métodos de extensión que se extienden HttpSessionState y HttpSessionStateBase simultáneamente:

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; 
    } 
} 

no estoy loco por esta solución, pero se siente como un paso, al menos, en una interesante dirección.

1

Desafortunadamente, ninguno de esos tipos tiene una clase de base común o una interfaz que pueda usar, por el momento deberá duplicar los métodos de extensión.

3

Se podría mantener su implementación inicial y utilizar HttpSessionStateWrapper para manejar el caso HttpSessionState:

SomeType t = new HttpSessionStateWrapper(SomeHttpSessionStateInstance) 
    .Get<SomeType>(); 
Cuestiones relacionadas