如何编写Session的扩展而无需为HttpSessionState和HttpSessionStateBase编写单独的方法?

时间:2010-06-18 22:23:23

标签: asp.net-mvc extension-methods httpsession

我为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
}

3 个答案:

答案 0 :(得分:3)

您可以保留初始实施并使用HttpSessionStateWrapper来处理HttpSessionState案例:

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

答案 1 :(得分: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;
    }
}

我并不为这个解决方案而疯狂,但这感觉就像是一个步骤,至少在一个有趣的方向。

答案 2 :(得分:1)

不幸的是,这些类型都没有可用的公共基类或接口 - 现在你必须复制扩展方法。