Wrap Your NameValue Variables

Tweet

ASP.NET gives a developer a lot of loosely typed key-value collections in which to stash stash variables, depending upon persistence needs. The short list includes ViewState, Session, Application and HttpContext.Items. These collections can come in very handy when one needs to keep an object around outside of a single request or shuttle things between different bits of the http pipeline. But it comes at a price—these collections are loosely typed, just returning Objects. Moreover, there is no compile-time checking to ensure that you are requesting the right key in the right place. Errors can lead to crashes at best, and interesting data corruption at worst.

But those issues can easily be avoided with a little discipline up front. You see, rather than calling these variables directly, it is very possible to wrap them in an appropriately-scoped property and have that manage access to the underlying data. For the examples we are going to use the Session, but the semantics will remain the same with just about any of the above collections.

So, let’s say we have a little web store. And this web store has a shopping cart. And we are going to stash this Shopping Cart object in the session. Now, one could many instances of code like this:


ShoppingCart sc=(ShoppingCart)Session[“ShoppingCart”];
If (sc==null)
{
      sc=new ShoppingCart();
}
//do stuff with ShoppingCart.

Or, one a base page class somewhere, you could define something like:


protected ShoppingCart Cart
{
    get
    {
        if (Session["ShoppingCart"] == null)
        {
            Session["ShoppingCart"] = new ShoppingCart();
        }
        return (ShoppingCart)Session["ShoppingCart"];
    }
}

The advantages of this approach are that the calling code never even needs to worry about where/how the shopping cart is stored, or if it can be null, or how to cast it out of the underlying store. Furthermore, if, at a future date, you decide that you are better off storing this cart in, say, the viewstate, the change is very, very easy because it only needs to be updated in one place.

Enjoy and don’t be afraid to kick it on DotNetKicks.com.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Anonymous

    off topic but,

    > Errors can lead to crashes at best,

    what do you mean by a crash though? how severe is it? the framework in question must be pretty fragile no; i mean a lack of encapsulation could cause so much damage?

    i’m not having a go (well, just a wee bit, but thats not the point) but maybe you could enlighten us lot who develop without this ‘state of the art’ framework from m$

    best regards, the doctor.

  • wwb_99

    Crashes mean application layer errors, not system-wide halts. You know, the kind of errors one gets all the time in loosely typed frameworks if one is not ultra careful about passing the right objects around to the right methods.

  • yacka

    What you’re saying is essentially good, but you’ve weakened the message by addressing two different issues, the loose typing of session and redundancy of code.

    As far as loose typing is concerned, I don’t see how your second example really improves on the first. You’re still assuming that the ‘ShoppingCart’ will be the correct type. An exception will occur if for some reason an object has been stored in the session using the same key. The code you’ve written is essentially the same, even if the latter has been separated to a base class and exposes the cart via a property.

    Perhaps a better example would be:

    
    protected ShoppingCart Cart  
    {  
       get  
       {
           ShoppingCart myCart = Session["ShoppingCart"] as ShoppingCart();
    	
           if(myCart == null)  
           {  
               myCart = new ShoppingCart();
    
    	   Session["ShoppingCart"] = myCart;
           }
    
           return myCart;
        }  
    } 
    

    This approach will always return a valid shopping cart without an exception, even if elsewhere ‘ShoppingCart’ has been used in the session for differently typed object. It’s a defensive approach that protects you against the unforseen and the loose typing of session.

    However none of this addresses what I think is your most important point, removing the redundancy of code. We could include the above code in each page where we need to access the cart, but that would create unnecessary maintenance overhead because we would need to update every instance of the code if anything changed.

    If you find you’re repeating code, find some way of isolating that code so it can be reused directly in all required circumstances. As you suggest, moving the code to a base class would be one method of achieving that.

  • Anonymous

    > Crashes mean application layer errors, not system-wide halts.

    well, thats not a crash then; its just your common garden error. a crash is something that brings the server down… nasty no?

    where do you .net developers get your terminology from? m$? god?

    the doctor

  • wwb_99

    @yacka: good points. The slightly different property wrapping is very good, but I like mine because, if I (or some other dev) was dumb enough to use the wrong name, something would blow up somewhere, whereas your approach would very effectively silently eat errors.

    @anon: Yes, it is a garden variety application layer error. But to end users, the server catching on fire and “there was an issue accessing the page” are the same thing and best avoided and/or caught during development.

  • http://www.totalpda.co.uk dhtmlgod

    However none of this addresses what I think is your most important point, removing the redundancy of code. We could include the above code in each page where we need to access the cart, but that would create unnecessary maintenance overhead because we would need to update every instance of the code if anything changed.

    Not if you do what Wyatt suggested and have it in a base page class and inherit from that.

  • yacka

    dhtmlgod,

    I know. I was re-emphasizing his point because it was confused with all the other stuff. The issues he describes are not addressed by removing code into a base class, it’s merely a different way of writing the same thing.

  • yacka

    Wyatt,

    That’s a fair point, but I thought you were trying to guarantee you had the correct type.

  • TheDeathart

    wow.. you wrote a singleton serializing to a session……