Monday, February 25, 2008

Making your own MVC - Convention problems

I use the usual naming conventions in my MVC. That is, if I want to see a list of plans, I navigate to /page.ashx/Plan/List.

That will cause my framework to call List on the PlanController. The controller action will then render the view located at /Views/Plan/List.aspx.

The controller action is also used as the default view name.

Problems with the naming conventions:
A view located at the following path, /Views/Plan/List.aspx, will create a List class in the Views.Plan namespace.
  • That causes ReSharper's intellisense to stop at Views.Plan, so it never sees the model class Plan located in the Models namespace.
  • The view List will shadow the generic List class.
  • Sometimes the compiler or ReSharper think I am using the namespace Plan, when I intend to use the Plan class.
Having similar names in namespaces and classes is not good. Nor is it good to have view names similar to other important classes, List being a prime example.

Problems with the default view name:
I guess this works flawlessly in Ruby on Rails, otherwise different conventions would be in use. But it doesn't work that well in .NET.

Default view name works fine when there are no dispatching between controller actions. There are no convenient way to detect the transition from one action to the next. Say we want to have a default action implemented, but also want to change what this should be in the future.

I would do it this way:
public class PlanController
{
public void Index()
{
List();
}

public void List()
{
// stuff data in ViewData
}
}
My intended behavior is to display the List-view. However, when the initial action is Index, then the Index-view is what will be displayed.

I could add a call to RenderView("List"), but I have two problems with that: First, it defeats the purpose of default viewnames, and second, I have to be careful to add a RenderView whenever this scenario arises.

See the problem with that? At some point, I will not discover this is the case and forget to call RenderView(). I am starting to think that a mandatory call to RenderView would be better, as that can't be forgotten.


Another problem I discovered, is the use of default view names. That is, the controller action is used as the viewname unless specified otherwise.

No comments: