ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions

A while back, I thought up the idea of the SmartBag, which has a very friendly API for working with viewdata objects.  With the December CTP, adding objects to ViewData was a bit difficult, but now that the ViewData property is an IDictionary on the Controller base class, getting objects in is very easy.  If you like this post, subscribe to my feed at http://feeds.feedburner.com/jeffreypalermo.

Consider the following usage

[Test]
public void ShouldRetrieveSingleObjectByType()
{
    var bag = new Dictionary<string, object>();
    var url = new Url("/asdf"); //arbitrary object
    bag.Add(url);
 
    Assert.That(bag.Get<Url>(), Is.EqualTo(url));
    Assert.That(bag.Get(typeof(Url)), Is.EqualTo(url));
}

We are adding a Url object to the dictionary, and then we can retrieve the object through the Get<T> method or by passing the type.  No need for a string key if only a single Url is in the dictionary.  If you have multiple Url objects, you can fall back to keys, or you can pass in a Url[] and then Get<Url[]>(). 

In CodeCampServer, I’ve removed SmartBag and added these ViewDataExtensions.  These are extension methods to IDictionary<string, object> and System.Web.Mvc.ViewData.  In my opinion, System.Web.Mvc.ViewData should inherit from Dictionary<string, object>, so maybe that will happen in the next release.

I’ve added ViewDataExtensions to MvcContrib, so you you’d like to use them, just build the trunk of MvcContrib, and you’ll have them.  Look at CodeCampServer for widespread use of these extension methods.  Strongly typed views don’t scale when the application complexity increases, but these view data extensions make working with the dictionary a snap.  My annoyance factor is very low with viewdata now.

MvcContrib is a free, open-source project.  Feel free to use it and contribute patches to it.  Building it takes less than 1 minute on my box, and the build runs all 840 unit tests to verify the features continue to work.