2010-06-18 96 views
6

我爲會話編寫了以下擴展方法,以便可以通過其類型持久保存和檢索對象。這適用於我的解決方案,但最終我不得不復制我的擴展方法來覆蓋舊的HttpSessionState和新的HttpSessionStateBase。我想找到一種方法讓這些回到兩套類型。有什麼想法嗎?如何爲Session創建擴展而無需爲HttpSessionState和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 
} 

回答

2

我發現了一個可行的答案,但有一些缺點。我希望有人能夠改進它。

@Andrew Hare說既不實現一個通用的基礎或接口。其實,他們確實如此。他們都實現IEnumerable和ICollection。問題是,通過這些信息,您是否想創建擴展方法來擴展IEnumerable或ICollection,這些擴展方法實際上僅用於Session?也許,也許不是。無論如何,在這裏是一種方法,與HttpSessionState和HttpSessionStateBase同時延長擴展方法消除重複:

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

我不是瘋了這個解決方案,但感覺就像一個步驟中,至少在一個有趣的方向。

1

不幸的是,這些類型都沒有共同的基類或接口,你可以使用 - 現在你將不得不復制擴展方法。

3

你可以保持您最初的實施和使用HttpSessionStateWrapper處理HttpSessionState情況:

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