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.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

9 Responses to ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions

  1. James Arendt says:

    For some reason, I had it in my head that ViewData already did implement IDictionary when I first read through your post.

    So, it did not make sense why inheriting from Dictionary would provide any benefit. But, ViewData does not implement any interfaces including IDictionary.

  2. @James,
    That is correct. And that’s a main reason why System.Web.Mvc.ViewData should implement IDictionary.

  3. James Arendt says:

    @Jeff:

    Both the generic and non-generic versions of the IDictionary interface inherit IEnumerable interfaces.

  4. @Steve,
    >Would be interested to know why. The current behavior supports more flexible late binding than would be possible with Dictionary.

    Inheriting from Dictionary would not take away any of the current capabilities. It would, however, add IEnumerable so we could explore the contents freely.

  5. @Victor,
    No here. Perhaps in another post.

  6. Greg says:

    oops … read it wrong … I was looking through the old tests which did the assert on equality and type … not this one …. my bad

  7. Greg Young says:

    Assert.That(bag.Get(), Is.EqualTo(url));

    Assert.That(bag.Get(typeof(Url)), Is.EqualTo(url));

    Can you explain why you use two asserts here?

    How about:

    Assert.IsTrue(bag.Get() == url);

    The code as presented seems really weird to me … are you worried that there may be an overriden comparison? Even if there is and it says the objects are the same when they are actually different shouldn’t you be honoring that?

  8. > >Strongly typed views don’t scale when the application complexity increases
    > Care to elaborate?
    They’ve been fine for me so far. What don’t you like about them?

    > In my opinion, System.Web.Mvc.ViewData should inherit from Dictionary
    Would be interested to know why. The current behavior supports more flexible late binding than would be possible with Dictionary
    .

  9. >Strongly typed views don’t scale when the application complexity increases

    Care to elaborate?

Leave a Reply