Я записал следующие дополнительные методы для Сессии так, чтобы я мог сохранить и получить объекты их типом. Это работает хорошо на мое решение, но я закончил тем, что имел необходимость копировать свои дополнительные методы для покрытия старого 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
}
Я нашел ответ, который работает, но с некоторыми недостатками. Я надеюсь, что кто-то сможет его улучшить.
@Andrew Hare сказал, что ни одна из них не реализует общую базу или интерфейс. Ну, вообще-то, есть. Оба они реализуют IEnumerable и ICollection. Вопрос в том, с этой информацией на буксире, хотите ли вы создать методы расширения, которые расширяют IEnumerable или ICollection, которые действительно предназначены только для сеанса? Может быть, а может и нет. В любом случае, вот способ удалить дублирование с помощью методов расширения, которые одновременно расширяют 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;
}
}
Я не без ума от этого решения, но это похоже на шаг, по крайней мере, в интересном направлении.
Вы можете сохранить свою первоначальную реализацию и использовать HttpSessionStateWrapper для обработки случая HttpSessionState
:
SomeType t = new HttpSessionStateWrapper(SomeHttpSessionStateInstance)
.Get<SomeType>();
К сожалению, ни один из этих типов не имеет общего базового класса или интерфейса, который вы могли бы использовать - пока что вам придется дублировать методы расширения.