Thursday, December 8, 2011

Using Dependency Injection with MVC

This is the code from the brief talk on Dependency Injection with MVC.
There are two projects here. This uses Unity, MVC3, and the UNity.MVC3 nuget package which has some additional code in it to handle lifetime management (ie objects that need disposal need special note in the bootstrapper.cs file.

IoC MVC Demos

Monday, December 5, 2011

Stop using MVC's ViewBag in most places, please!

Even the built in templates give us support for ViewBag. The scaffolding templates create ViewBag.SomeEnumerable to use for our pages.
Sure - its quick code and since it's auto-generated will likely work ok. The problem comes in from the fact that ViewBag is a dynamic object. There are no compile time type checks. If you misspell something you won't be notified from the compiler.

I've seen this used in such bad ways, I would love to see it's usage curbed and applications cleaned up.

So in a controller:
ViewBag.SomeProperty = "10"
and in the view:
@ViewBag.Som3Pr0p3rty
We won't ever know of this error. It won't even generate a runtime error since the misspelled name just generated a null.


Use ViewModels and save yourself from these potential problems. Our templates set a page title in ViewBag as well.


There are several options in setting a page title. Since this is a well known property one could argue that using it just for Title is ok. I wouldn't argue this. There are other options.
1. Set it in a section in the layout and render it from the client.
2. Use ViewBag.Title
3. Use a filter (seems much too complicated for a title)
4. Use a Model.Title field.

Since by default we have a ViewBag.Title field created and our templates also get it by default, I'll yield that in this case, its ok.

What about select lists?
Rather than the default

 ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "FirstName", order.CustomerId);


Do something like
yourViewModel.Customers = customers; //a loaded collection

and in your view
@Html.DropDownListFor(x => x.CustomerId, new SelectList(Model.Customers, "CustomerId", "Name"))

Or if you prefer to set your ViewModel to contain the SelectList


yourViewModel.Customers = new SelectList(db.Customers, "CustomerId", "Name", order.CustomerId);

and now your view would be slightly cleaner as:
@Html.DropDownListFor(x => x.CustomerId, x.Customers)

See, that's not so difficult now is it? Enjoy!