ASP.NET MVC: Driving partials by convention
I like to have conventions in the code I write – I find it makes the code i write much cleaner which still providing flexibility.
One of the conventions that Jeremy Miller coined for working with ASP.NET MVC applications is that of using one model per controller method aka "The Thunderdome principle". I think we can take this further by having one model per partial that we use inside our views.
The benefit of having a model especially for a partial is that we remove confusion about data available to populate our controls by restricting the amount of data we actually have. It also makes more sense from a conceptual point of view.
Given this approach it started to become quite annoying having to type the following code all the time.
<% Html.RenderPartial("_Foo", new FooModel()); %>
We realised that a neater approach would be if we could just pass in the model and it would work out which partial needed to be rendered, assuming the convention that each model is only used on one partial.
We are using strongly typed models on our views so the code behind in each of the partials extends ViewPage
public static class HtmlHelperExtensions { public static void RenderPartialFrom(this HtmlHelper htmlHelper, object model) { var thePartial = FindMeThePartial(model); htmlHelper.RenderPartial(thePartial, model); } private static string FindMeThePartial<T>(T model) where T : class { var projectAssembly = Assembly.Load("Project"); var types = projectAssembly.GetTypes(); foreach (var type in types) { if (type.BaseType == typeof(ViewPage<T>)) { return type.Name; } } return string.Empty; } }
You can then refer to this in views like so:
<% Html.RenderPartialFrom(new FooModel()); %>
Obviously it takes the first result it finds, so the convention we have is that each model should only be used on one partial which I think is a reasonable idea.
This looks good! I understand that this is proof of concept and I dont want to be the one for premature optimisation – But, I think we can agree that we are better off if we cached all the types descending of ViewPage in a dictionary and then used that to resolve the referencing view rather than load the assembly and iterate through all the types each time.
Cheers,
Tasos
Anastasiosyal
23 Feb 09 at 10:06 pm
[...] to VoteASP.NET MVC: Driving partials by convention (2/20/2009)Friday, February 20, 2009 from Mark NeedhamI like to have conventions in the code I write – I find [...]
ASP.NET MVC Archived Blog Posts, Page 1
24 Feb 09 at 12:51 am
Very Cool!!
Have You considered what this would look like using an IOC container? All of the major ones have generic type resolution. Jeremy Miller has a blog post about how to do it with StructureMap
John Teague
24 Feb 09 at 1:13 am
[...] of the problems we can encounter when using partials throughout our views is how we should create the model needed for those [...]
ASP.NET MVC: Using Adaptors for partial models at Mark Needham
3 Mar 09 at 11:59 pm