4
\$\begingroup\$

I have two types of session wrappers:

Type 1

public class SessionHandler
{
    public static SessionHandler CurrentSession
    {
        get
        {
            SessionHandler session =
              (SessionHandler)HttpContext.Current.Session["SessionId"];
            if (session == null)
            {
                session = new SessionHandler();
                HttpContext.Current.Session["SessionId"] = session;
            }
            return session;
        }
    }

    public int? UserId { get; set; }
}

Type 2

public static class SessionHandler
{
    private static void SetSession<T>(string sessionId, T value)
    {
        HttpContext.Current.Session[sessionId] = value;
    }

    private static T GetSession<T>(string sessionId)
    {
        return (T)HttpContext.Current.Session[sessionId];
    }

    public static int? UserId
    {
        get
        {
            return GetSession<int>("UserId");
        }
        set
        {
            SetSession<int>("UserId", value);
        }
    }
}

The usage is as follows:

//Type 1
SessionHandler.CurrentSession.UserId = 10;
//Type 2
SessionHandler.UserId = 10;

Please suggest which one is better and why.

What I think about type 1:

Good for readability and maintainability. I can add more properties with less efforts, but the session will become heavy (single session for whole application). This approach may not be good, if we have more sessions to store. However, I'm not sure whether assignment/retrieving the session is just changing the reference or does some serialization/de-serialization.

What I think about type 2:

Usage is easy, but it needs little work while adding more sessions. This is the same as a normal session usage but, it just avoids the typos which might happen frequently while retrieving the sessions on various places.

\$\endgroup\$
1
  • \$\begingroup\$ Type 1 allows for inheritance, interface implementation and overall a better way to do unit testing. static classes should only be used when there is absolutely, positively, no way state needs to be maintained. Also, please note that the way it is written, it is not thread-safe. \$\endgroup\$ May 21, 2012 at 14:38

2 Answers 2

2
\$\begingroup\$
private static T GetSession<T>(string sessionId)
{
    return (T)HttpContext.Current.Session[sessionId];
}

The above code will throw an exception if the value is not present.

Consider something like the following:

    private static T GetSession<T>(string sessionId)
    {
        T val = default(T);
        var session = HttpContext.Current.Session;

        if (session[sessionId] != null)
        {
            val = (T)session[sessionId];
        }

        return val;
    }
\$\endgroup\$
0
1
\$\begingroup\$

Alternatively you might want to consider using enums that have string values attached to them. There is an article detailing how you can make that work with attributes.

That way you can define an enum with all the keys that you want to store values in your session with like this:

public enum SessionKey {

    [StringValue("UserId")]
    UserId,

    [StringValue("UserName")]
    UserName,

    [StringValue("Hcskn")]
    HighlyComplexSessionKeyName

}

In your session wrapper you can have methods (such as a GetInt(SessionKey.UserId) or GetString(SessionKey.UserName)) that retrieve the values for you. This way you can be completely sure that you don't use the wrong string to retrieve values from the session and it is somewhat typesafe.

The only drawback is the amount of initial code you need to set it all up for you. The advantage is that it is easy to add new variable keys to store session values in as you only need to add that to the SessionKey enum.


EDIT:

As Chuck pointed out in comments: If the names on the enum values are enough then you can use ToString method on the enum to get the string representation. E.g.:

Console.Write(Session.Key.UserId.ToString()); 
// prints "UserId"
\$\endgroup\$
5
  • \$\begingroup\$ I was on holiday and couldn't come online(however, I watched your answer on mobile but couldn't reply). Coming to the answer, even though the approach is good to have string values on enum; I don't see any advantage to implement this approach for sessions(other than typo issue). This will be an additional burden and the performance become worse just to avoid the typos. I might be wrong, please correct me in that case. \$\endgroup\$
    – Knvn
    Apr 16, 2012 at 9:37
  • \$\begingroup\$ I flagged the question for moderator attention. Lets see if they can move it. \$\endgroup\$
    – Spoike
    Apr 17, 2012 at 8:32
  • 1
    \$\begingroup\$ @Knvn: Enums are type safe, which is another advantage (or disadvantage if you come from a dynamic programming background). If it's an performance issue then that claim should always be backed up with measurable test or else you'll be prematurely optimizing stuff. :-) But most likely it isn't an issue when it comes to enums as they are type safe and have (pretty much afaik) direct access and I think the performance hit is negligible when the string value has to be retrieved. But then again, it all depends on the website how much traffic it gets. \$\endgroup\$
    – Spoike
    Apr 17, 2012 at 8:40
  • \$\begingroup\$ Why go to all the trouble of the StringValue attribute when you can call "ToString" on the enum and get the name of the value? \$\endgroup\$ May 21, 2012 at 17:53
  • \$\begingroup\$ @ChuckConway That way you can have string values that does not correspond to the name of the enum value. I'll update the answer to show this. \$\endgroup\$
    – Spoike
    May 22, 2012 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.