CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo [MVP]

Software management consultant and CTO, Headspring Systems

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.



Comments

Victor Kornov said:

>Strongly typed views don't scale when the application complexity increases

Care to elaborate?

# March 26, 2008 6:20 PM

Steve Sanderson said:

> >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<string, object>

Would be interested to know why. The current behavior supports more flexible late binding than would be possible with Dictionary<string,object>.

# March 27, 2008 11:39 AM

Greg said:

   Assert.That(bag.Get<Url>(), 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>() == 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?

# March 27, 2008 11:45 AM

Greg said:

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

# March 27, 2008 12:46 PM

Jeffrey Palermo said:

@Victor,

No here.  Perhaps in another post.

# March 27, 2008 11:09 PM

Jeffrey Palermo said:

@Steve,

>Would be interested to know why. The current behavior supports more flexible late binding than would be possible with Dictionary<string,object>.

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

# March 27, 2008 11:10 PM

James Arendt said:

@Jeff:

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

# March 28, 2008 10:53 AM

Jeffrey Palermo said:

@James,

That is correct.  And that's a main reason why System.Web.Mvc.ViewData should implement IDictionary.

# March 28, 2008 11:17 AM

James Arendt said:

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.

# March 28, 2008 2:21 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

This Blog

Syndication