D'Arcy from Winnipeg
Solution Architecture, Business & Entrepreneurship, Microsoft, and Adoption

ASP.NET - Creating a Strongly Typed State Variable Class

Monday, December 24, 2007 11:36 AM

With ASP.NET, we have a bunch of different ways to store data that we want to persist across postbacks: values in session, querystring, viewstate, cookies, etc.

One thing that I'm very adamant about is ensuring that these values are enforced with strong typing. Without strong typing, you end up doing a few things:

1. You open yourself up to errors because of typos in the variable names or in duplicate names with differing uses.

This one speaks for itself. Because most of the storage methods allow you to identify the variable with a string value (i.e. "MySessionVariable"), its easy for someone to make a typo. At the least, this will mean errors and extra time wasted in debugging silly spelling mistakes. At the worst, someone has either started using the same session variable name for a totally different purpose elsewhere in the app...which means your string value is also being used somewhere to hold a date...and errors ensue.

2. You end up implementing duplicate accessability code throughout your app

Each method has different syntax, and (IMO) having Session("SomeValue") all over your code just looks messy.

3. You need to ensure proper casting throughout your code and relying on the developer to cast properly.

Let's add on top of point #2: not only do you need to write your accessibility code all over the place, but you also need to cast your value back to whatever it originally was. So now you have

CType(Session("SomeValue"), SomeType)

all over the place. Not sexy.

4. You create a maintainability issue if you ever decide to change a name or method of storing.

So you have a bunch of values being stored in ViewState and your application is working beautifully...until the dev lead reads some article and decides that ALL of those values now need to be ported to Session variables, and that there are some that will be converted to QueryString variables as well. Now what do you do? You go for a hunt through your code changing everything. And what if you changed the name of the variable? You're going through your code as well. Now yes, you could make an argument that this is as easy as find/replace...but would *you* guarantee that a sweeping change like that would be 100% bug free as a result?

The Solution

Luckily there's an easy solution to these items, and it gives you the best of both worlds: flexibility of storing your values wherever you want, with very little maintenance impact in your application.

Consider the below Session variable:

Session("MyShoppingCart") = New ShoppingCart

Here we create a new ShoppingCart object which will be a collection of Product objects. This will be stored in Session. If I want to access this in my code, I need to do something like this:

Dim scShoppingCart as ShoppingCart = CType(Session("MyShoppingCart"), ShoppingCart)

If I wanted to get the collection of products, I could access a function called GetProducts as such:

CType(Session("MyShoppingCart"), ShoppingCart).GetProducts( )

Do you see the issues here?

- I'm relying on the developer to know what my type is
- I'm writing out a lot of code that's really messing up the code file
- I'm assuming that the session variable name and the type will never change

So how can we abstract this out a bit...add some layers that will remove the need for the developer to know so much of what's going on under the hood?

We're going to create a class called "ShoppingSession" which will wrap around our session variable:

Imports System.Web.HttpContext

Public Class ShoppingSession

    Shared Property CurrentShoppingCart() As ShoppingCart
        Get
            Return
Current.Session("ShoppingCart")
        End Get
        Set
(ByVal value As ShoppingCart)
            Current.Session("ShoppingCart") = value
       End Set
    End Property

End Class

The reference to System.Web.HTTPContext allows us to access the session variables from within a non-page inherited class.

When we access this from our code, we can now get the current shopping cart by going:

ShoppingSession.CurrentShoppingCart

or if we wanted to access the Products collection from the ShoppingCart object:

ShoppingSession.CurrentShoppingCart.GetProducts()

This is because our property is declared as Shared, so we never have to actually create an instance of ShoppingSession...you can just use its shared properties to access the session/viewstate/etc. values.

In this property for CurrentShoppingCart, we're now able to access a strongly typed instance of a ShoppingCart without having to know ANYTHING about its storage mechanism. What if ShoppingCart ended up changing its implementation to Viewstate, or maybe some custom solution where the value was persisted in a database, or whatever...our code doesn't care, because our new class shields us from it. The property will take care of the casting if required, and we just enjoy the benefits of not having to deal with it.

This also let's us add extra validation around our state variables. What if we only want a specific datatype, or a specific state of an object (maybe we don't want to store a ShoppingCart unless there's at least one item in it). Without abstracting it out to a seperate class, you'd have to write all that code in with whatever code is using/assigning the values. With our new solution you can localize all the validation into one nice, neat, tidy package.

What if the variable name changes? You change it in one place and that's it...your property name doesn't need to change, which means none of your code needs to change.

The reality is that you will have values that you'll want to store accross postbacks and make available in your application. Proper management of these values goes a long way to ensure your asp.net app will be easily maintainable and with less bugs and code.

D




Feedback

# re: ASP.NET - Creating a Strongly Typed State Variable Class

Good idea, really. it's the first time I see the "Current" for the session but it's easily understandable.
9/1/2008 12:00 PM | Max

Post a comment