Extension methods and a plea for mixins

I was having a spot of trouble the other day trying to get my extension methods to show up in my ASP.NET MVC Views.  One of the issues we’ve run into is trying to make our Views (more) intelligent on the HTML they create.  Our Views still only work off of a Model, but they can be much more intelligent on creating the HTML for a single property, or group of properties.  However, if we’re trying to extend our Views (and not that crazy HtmlHelper), there are at least 6 View types we have to deal with:

  • ViewUserControl
  • ViewUserControl<TModel>
  • ViewPage
  • ViewPage<TModel>
  • ViewMasterPage
  • ViewMasterPage<TModel>

Now, at least the generic types inherit from their counterpart (ViewPage<TModel> inherits ViewPage).  However, no real correlation exists between the six types, other than IViewDataContainer for the most part (which the ViewMasterPages do NOT implement).  We noticed quite a bit of duplication in our common base behavior for each of these types.  Since we couldn’t make all of these inherit from the same type, making extension methods off of a common interface seemed to make sense:

public static class ViewBaseExtensions
{
    public static string HtmlFor<TModel>(this IViewBase view, 
        Expression<Func<TModel, object>> modelExpression)
    {
        // Zomething interesting
    }
}

Since I was working in the View, I expected my HtmlFor method to show up as an extension method.  Even after some helpful tweets from folks, nothing seemed to work; my extension methods simply did not show up.  What was my problem?  Here’s a simplified example:

public static class FooExtensions
{
    public static void Bar(this Foo foo)
    {
    }
}

public class Foo
{
    public void PrettyPlease()
    {
        Bar(); // Does not compile
        this.Bar(); // Not so magic :( 
    }
}

I defined an extension method for the Foo type, but tried to use it inside Foo.  Well, that doesn’t work unless I call the extension method directly on an instance of Foo, which leads me to use the “this” keyword.  Which is why you see examples like these that make prodigious use of the “this” keyword.

Duplication be damned, all that “this” nonsense just isn’t worth it.  Especially when you realize that it’s only there to initiate the extension method compiler magic.

In the end, this is just another example that extension methods aren’t mixins, and I seriously doubt the new C# 4.0 “dynamic” keyword will do the trick.  I’m starting to believe that if I want a dynamic language, I should stop looking for a static language to bend yoga-style backwards to be one.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in ASP.NET MVC, C#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://eventsavvi.com A’braham Barakhyahu

    Castle’s Dynamic Proxy & (possibly) System.Addin will provide mixin functionality.

  • http://weblogs.asp.net/scottgu ScottGu

    HtmlHelper and AjaxHelper will be extended with the MVC RC release to support a HtmlHelper and AjaxHelper signature. This allows you to write extension methods that support expressions against the model, and which do not require using the this keyword.

    For examplel you could easily enable:

    Html.TextBoxFor(m=>m.ProductName);

    I have a small example of this in my blog post here: http://weblogs.asp.net/scottgu/archive/2008/12/19/asp-net-mvc-design-gallery-and-upcoming-view-improvements-with-the-asp-net-mvc-release-candidate.aspx

    Hope this helps,

    Scott

  • http://scottbellware.com Scott Bellware

    > I’m starting to believe that if I want a dynamic language, I should stop
    > looking for a static language to bend yoga-style backwards to be one.

    No! Really? :)

    And if you don’t start making the transition, you’ll likely to be swept up in the predictable static language attachment inanity that will come with .NET contracts in .NET 4.

    Yes, it’s time to seriously expand you understanding, your mind, and your horizons, and stop being led around by the nose by a company that produces software in ways that you know to be deeply invested in denial and ignorance.

  • http://www.lostechies.com/members/schambers/default.aspx schambers

    It’s funny you should post about this. I myself have just begun getting under way with ruby. It feels like they are indeed heading down a dark path in the clr. as someone mentioned to me the other day, “cruft on top of cruft”