Logo




Subscribe:
RSS 2.0 | Atom 1.0
Categories:

Sign In


[Giagnocavo]Michael::Write()

# Tuesday, August 26, 2008
ASP.NET MVC - Abusing Using (At VB's request?)
Someone on our team started using ASP.NET MVC for a new web interface we're doing. I must say I'm impressed with the level that the MVC team [ab]uses the C# compiler, mostly in a good way. On the plus side, they end up with a bit more compiler time checking than would be possible otherwise (we can only hope WPF will follow suit some day).

But one thing struck me odd was how their helper method for generating an HTML form works. The goal is to generate an HTML form tag with the right action, and they use lambdas as symbolic references to figure out the action. The next problem is making sure that the <form> gets closed with a </form>. The straightforward answer to this is "create a function that takes a function". The C# signature would be: void Form<A>(Expression<Action<A>>, Action). Then your ASPX code would be:

<% Html.Form<FooController>(x => x.Edit(someVar.FieldX), () => { %>
    Some Html <% SomeCode%>
<% }); %>

The code is nicely bracketed and works fine. But ASP.NET MVC doesn't actually do that. Instead, the Form method returns an IDisposable! The code to use it is:

<% using (Html.Form<FooController>(x => x.Edit(someVar.FieldX)) { %>
    Some Html <% SomeCode%>
<% } %>

Why do they use an IDisposable? The rest of the MVC framework seems to assumes people are somewhat familiar with lambdas, closures and what not. The only thing I can think of is that VB doesn't support anonymous methods. So in order to make it VB friendly, they come up with quite a strange use of IDisposable to abuse language support for it. Overall, I'm not sure if this is dumb or cute.

Code | ASP.NET
Tuesday, August 26, 2008 9:19:59 PM UTC  #    Comments [4]  |  Trackback

Wednesday, August 27, 2008 1:15:59 AM UTC
It's neither dumb nor cute. It's brilliant, and I think this should be done more often, if only because "});" is a terrible looking token sequence. :-)

Such "abuses" of IDisposable aren't new -- they've been done for locking before (e.g. http://monotorrent.blogspot.com/2007/04/i-was-just-talking-to-guy-about-some-if.html).

It's perhaps less useful now that we have anonymous delegates and lambdas, but in C# 1 it was a very useful technique for writing scope-based begin/end code.
Wednesday, August 27, 2008 1:29:57 AM UTC
Using IDisposable with a lock makes a lot more sense: You need the lock to be freed when an exception is thrown. Ditto for a transaction. But for use as a non-exception case block?

The fact that C# 1 _REQUIRED_ this kinda thing is just another criticism of C#. Same for the fact that VB still requires this. And that C# "});" looks bad? Again, fault of C# for not having lightweight syntax? :)

At any rate, "cute" is a compliment -- I dunno why it wouldn't be "cute". Dumb is just for the fact that people still have to accommodate VB?
Wednesday, August 27, 2008 3:16:17 PM UTC
I think it is because it generates shorter and faster code.
Wednesday, August 27, 2008 8:33:12 PM UTC
Boris, well, I'd sure hope that's not the ONLY reason :). If the JIT can't handle something like that efficiently, then I'd be pretty sad.
OpenID
Please login with either your OpenID above, or your details below.
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview