Configuration over Convention
A few days ago there was a discussion on the ALT.Net mailing list about some of the design choices that the MS MVC team has made.
Specifically, the issue of [ControllerAction] and explicit RenderView() came up. Rob Conery just posted a 6 pages post that goes over how to deal with the pain of this decision.
From his post:
I’ve been working a lot with the new MVC bits and one thing that’s annoying is having to type the same stuff, over and over. One in particular is the Controller Action:
Rather than type this over and over, I decided to make a snippet.
My stand on this is that this is a case of trying to use the tools to fix awkward design.
Microsoft has reasons for those decisions, they are worried about people accidentally exposing public methods on controllers that can be remotely routed, and they said that they didn't like the CancelView() that you need to use if you don't want to use the default view.
Those are valid reasons, and they fit the usual mind set from Microsoft, but I feel they are making a mistake. Both issues are a case of shifting the burden to the user, which is the wrong way to do when you are trying to get a usable framework. As evidence by the annoyance factor that it can cause.
Usability matters, and stuff like that hurts the flow of the work.
The pain I was talking about was typing and your wrists :). I don't see an issue with [ControllerAction] really - it's nice and safe and follows the same pattern as WebMethod.
Burdens, pain, hurting... geez you'd think we're talking about substance abuse here. Give me a good reason why being Explicit is not a good thing (in the case of RenderView).
Also - I'm sending some happy juice and a teddy bear to you :). I think you need a hug :):).
Why do you think that typing and wrist pain are not important?
I would have the same issue with [WebMethod], if there was another WS framework that said that anything public on a class inheriting from a WebService is a web method.
Explicit is not a good thing because the highly common case means that you are going to specify something that the framework can do for you. For me, this means that I need to do work for the framework, instead of the other way around.
Make sure that the teddy has a green jacket and a red tie, please.
Then, just make sure that the mechanism to 'reflect' controller action is extendible and plugin your own logic.
That is assigning the work to someone else.
That is assigning the work to someone else.
@ayende: I posted about this myself over at my blog a while back and the response that I got was that this was because of a security thing that prevents unknowing developers from opening up their application to the world.
My response: so, Microsoft continues to coddle developers who cannot properly factor an application. System.MVC is SUPPOSED to promote separation of concerns. If concerns are separated, something that should be accessible shouldnt be on the controller.
Just to clarify: my comment was supposed to say
If concerns are separated something that should not be accessible shouldnt be on the controller.
In practice, is it easy to have everything that shouldn't be accessible, not on a controller? I'm talking for decently complex MVC apps, not toy examples that explain nothing other than syntax.
A solution for Microsoft would be to have FxCop chew you out if you don't write tests (which are clearly testing a browser hitting that method, if this makes sense) for all the non-hidden methods on a controller.
There's something to be said for enabling a "pit of success". I clearly recall Scott Guthrie explaining that would could alter the defaults by creating "some class" that would take care of all this stuff. It seems that you would want to override other issues as well, so why again is this a huge issue?
In this particular case I'd have to disagree with the complaint and side with the chosen approach. Maybe a class-level attribute that "opens up" the public methods by default could help remedy this situation but I still think methods should be unavailable by default.
This is a valuable lesson learned form other frameworks (even RoR) that cause apps to expose methods as actions by accident.
I'm not convinced that all public methods in a controller must be actions but I'm willing to change my mind after I have a chance to build non-trivial stuff on it.
I agree with Sergio - a class level attribute to change the default would be the best way to go... If they just made all methods accessible by default, everyone would jump on the 'MS MVC is not secure' bandwagon as soon as some dimwit's site got hacked because of this.
I never really considered "coddling developers" as being contradictory to usability, but it makes a fair amount of sense. If the habits of your developers becomes a literal embodiment in your architecture, then you've changed the external problem domain to include developers habits in addition to user habits. Makes sense.
My thanks go out to Ayende and Matt Berther.
I have a feeling most of you guys haven't coded a project on MonoRail/Ruby on Rails. Convention over Configuration IS VERY IMPORTANT. The point is not just wrist pain (which I am suffering already), its the neatness of debugging. When you have something 95% you need to do and you keep coding it again and again that naturally means you are giving pain to your developer fellows to understand the code later. Thats what we blamed about MS Patterns (e.g. Exception vs Log4Net, Object Builder versus Castle Windsor), and Spring (thats how people love Rails).
When you want to know its important or not, try the other side first is very important step to justify.
Did you see Phil Haack's post on his ConventionController?
Basically, descending from ConventionController rather that Controller allows you to bypass all the attributes for you methods.