The MVC3 special sauce in POP Forums
I was chatting with a friend about why, as much as I would rather not rewrite POP Forums for the bazillionth time, it has actually been a lot of fun, and smooth sailing on MVC. If you haven't been playing along at home, POP Forums is the forum app that I've been maintaining now since the days of ASP.old, in sites like CoasterBuzz. In late 2009, I decided I'd rewrite it from the ground up as an MVC app, but it was slow going after the birth of my child. But when I did find time to write code, especially in the last few months, it went relatively quickly because MVC is so flippin' easy to use. The first beta has been posted to CodePlex.
So here's what I dig about using MVC3, and why v9 of the forums will probably be the best version so far...
The Razor view engine. It's simple, it's clean, and it makes you remember those days of creating HTML pages when that Internet thing first looked like it might stick around for awhile. Actually, the WebForms views were already a step in the right direction, in terms of creating exactly the markup you wanted, but Razor just blows this simplicity out of the water. It's an AJAX world, baby, and the more finely you can control the markup, the more you enjoy manipulating stuff on the page.
Dependency injection done right. Controllers, views, action method filters... they all wire up to your code effortlessly with the simple IDependencyResolver interface. You can use any DI container you want... Ninject, StructureMap, etc., and all you need to do is fill out this interface and specify an instance in the app start of global.asax. MVC will fill out your cascade of objects for you.
Let me spell this out in case you aren't sure why this matters. If you have a controller that takes an IWhack object in the constructor, MVC will use the dependency resolver to figure out what to pass that constructor. So if your DI container maps IWhack to the class SuperWhack (which implements IWhack), then that's what the controller will receive. If SuperWhack requires an ISmack in its constructor, the resolver will look for that mapping as well.
I bring this up to point out that you can stub-out or mock these interfaces and test each class, including controllers, in isolation of each other. That's really one of the biggest wins of using MVC. If the controller uses an IWhack to get some data, you can test that your action method calls the IWhack, and passes its data to the view. That has been covered elsewhere in a million blog posts, but I figured it was worth stating again here.
Areas. This routing feature of MVC doesn't get a lot of love, but it's a real time saver in terms of organization and integration. The forum is implemented as an area, which means that all of its views are nicely packaged in /Areas/PopForums/Views. That there is an AccountController and associated views is OK if the app I'm dropping the forum into also has an AccountController, because the project structure keeps them all separate.
Global Filters. This is one of my favorite things in MVC3. Filters are implemented using an attribute you put on methods or entire controllers in order to restrict methods to certain users, do some logging, etc. The thing is, there are times when you'd like to do something on every call to an action across all controllers, and these global filters do just that. In many ways, they're actually used in a similar fashion to HttpModules in WebForms, only with a much shorter list of "events" to worry about. In POP Forums, I use a global filter to establish the user's identity before an action is called.
If you haven't yet taken the leap into MVC, do it! There are a ton of great resources on the ASP.NET site to get you started. Meanwhile, visit CodePlex and get the POP Forums bits, and give it a whirl. As you'll see in the release notes, a streamlined install is still in the works, but I think you can make it work locally. You can even try it out on my server. Be sure to leave feedback in the appropriate place on CodePlex.