Thursday, December 24, 2009

Session with Style

Sloppy code, unfortunately, is ubiquitous. Sometimes it's due to laziness; other times to ignorance, as in: "it never even occurred to me to do it otherwise." I'd put the example I use in this post as one of the latter for most people.

So you want to store something in Session? Easy.

Session["MyString"] = "this is a string I'm storing in session."

Then, somewhere else in your application you do:

MyLabel.Text = (string)Session["MyString"]; 

Maybe "sloppy" is too strong a word. But it certainly isn't slick--for a number of reasons: casting, remembering keys, key typos, overwriting existing keys, etc.

An incrementally better solution might be to use an enumeration or constants for the keys. A step beyond that would be to put all of your Session-related information into a single class and store that in Session.

Let's bump it up a level. Let's take this to 11. Here's a much better way.

Start with a base class you can reuse in any of your ASP.NET applications.

using System;
using System.Web;

namespace MyNamespace
{
    public class SessionInfo<Subclass>
        where Subclass : SessionInfo<Subclass>, new()
    {
        private static string Key
        {
            get { return typeof(SessionInfo<Subclass>).FullName; }
        }

        private static Subclass Value
        {
            get { return (Subclass) HttpContext.Current.Session[Key]; }
            set { HttpContext.Current.Session[Key] = value; }
        }

        public static Subclass Current
        {
            get
            {
                var instance = Value;
                if (instance == null)
                    lock (typeof(Subclass)) // not ideal to lock on a type -- but it'll work
                    {
                        // standard lock double-check
                        instance = Value;
                        if (instance == null)
                            Value = instance = new Subclass();
                    }
                return instance;
            }
        }
    }
}

Now, create a class specific to your current application.

public class MySessionInfo : SessionInfo<MySessionInfo>
{
   public string SomeString { get; set; }
}

To use it in your application, simply do:

// set the value
MySessionInfo.Current.SomeString = "this is a string I'm storing in session.";

// get the value
MyLabel.Text = MySessionInfo.Current.SomeString;

Of course, you can put more than just strings into your subclass. You can create separate subclasses for use in unrelated parts of your application, or you can create a single class (if the design calls for it) to store everything you'll need to have in Session. Perhaps something like:

public class MySessionInfo : SessionInfo<MySessionInfo>
{
   public WebSiteMember WebSiteMember { get; set; }
   public ShoppingCart ShoppingCart { get; set; }
   public BrowseHistory BrowseHistory { get; set; }
}

Just remember that if you'll be using anything other than in-process session state, you'll have to make your class serializable.

1 comments:

Simerman said...

This solution does not work if you want to access the Session value in a declarative fashion as a Select Parameter for a Data Source.

Post a Comment