2010-06-18 9 views
6

Ho scritto i seguenti metodi di estensione per Session in modo che possa persistere e recuperare gli oggetti in base al loro tipo. Funziona bene per la mia soluzione, ma alla fine ho dovuto duplicare i miei metodi di estensione per coprire il vecchio HttpSessionState e il nuovo HttpSessionStateBase. Mi piacerebbe trovare un modo per ridurli a un set che copre entrambi i tipi. qualche idea?Come posso scrivere estensioni per Session senza dover scrivere metodi separati per HttpSessionState e 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 
} 

risposta

2

Ho trovato una risposta che funziona, ma ci sono alcuni inconvenienti. Spero che qualcuno sarà in grado di migliorare su di esso.

@Andrew Hare ha detto che nessuno dei due implementa una base o un'interfaccia comune. Beh, in realtà, lo fanno. Entrambi implementano IEnumerable e ICollection. La domanda è, con quelle informazioni al seguito, vuoi creare metodi di estensione che estendano IEnumerable o ICollection che sono realmente solo per Session? Forse sì forse no. In ogni caso, ecco un modo per rimuovere la duplicazione con metodi di estensione che estendono HttpSessionState e HttpSessionStateBase simultaneamente:

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

io non sono pazzo di questa soluzione, ma ci si sente come un passo, almeno, in un interessante direzione.

1

Purtroppo nessuno di questi tipi hanno una classe base comune o interfaccia è possibile utilizzare - per ora si dovrà duplicare i metodi di estensione.

3

si potrebbe tenere l'implementazione iniziale e utilizzare HttpSessionStateWrapper per gestire il caso HttpSessionState:

SomeType t = new HttpSessionStateWrapper(SomeHttpSessionStateInstance) 
    .Get<SomeType>(); 
Problemi correlati