Sunday, January 25, 2009

ReaderWriterLockSlim

I had totally missed that there was a new class added to the System.Threading namespace in version 3.5 of the .Net framework, namely the System.Threading.ReaderWriterLockSlim class. This is more or less a total replacement for the ReaderWriterLock-class and the wacky name is because they had to leave the old class in, mostly for compatibility reasons. Joe Duffy has a nice post about it here.

Technorati-taggar: ,,,

Saturday, January 24, 2009

SOLID

Robert “Uncle Bob” C. Martin coined the acronym SOLID a couple of years ago and though I’m fairly familiar with all of the principles I’d like to really make sure I’ve understood them all so I think I’m going to write a little series, one post for each principle. As the first post here’s a list of the principles.

 

  • Single responsibility principle
  • Open closed principle
  • Liskov substitution principle (way cool name)
  • Interface segregation principle
  • Dependency inversion principle

You sound so smart when saying things that ends in –principle.

Check out Scott Hanselman’s interview with uncle Bob on Hanselminutes.

Monday, January 5, 2009

HtmlTextWriter fluent interface

EDIT: The code demonstrated in the article is part of the Legend open source project you can find at http://legend.codeplex.com/.

If you've ever created a web control - and God knows I've created a few of them - you've most definitely come in contact with the HtmlTextWriter. If you have you've probably sworn a couple of times over how clunky it is. The amount of code you have to write to create quite simple pieces of html is just insane.

For example, take this very basic html tag:

<div id="id" name="name" class="class">Lorem ipsum.</div>

To create the same output with the HtmlTextWriter you'd have to write the following:

public void Render(HtmlTextWriter writer)
{
    writer.AddAttribute(HtmlTextWriterAttribute.Id, "id");
    writer.AddAttribute(HtmlTextWriterAttribute.Name, "name");
    writer.AddAttribute(HtmlTextWriterAttribute.Class, "class");
    writer.RenderBeginTag(HtmlTextWriterTag.Div);
    writer.Write("Lorem ipsum.");
    writer.RenderEndTag();
}

Now, you might think that that's a lot of code to accomplish very little, but that's not what's worst, it's utterly unmaintainable. Let's say we have more than one tag to render, and possibly child-tags of these tags, it soon becomes very hard to tell where a tag starts and ends and the structure of the output is hidden behind this procedural code. Well, what can we do to solve this? Extension methods to the rescue, what if we could write the above code in the following manner:

public void Render(HtmlTextWriter writer)
{
    writer
        .Tag(HtmlTextWriterTag.Div, e => e.Id("id").Name("name").Class("class"))
            .Text("Lorem ipsum.")
        .EndTag();
}

The "Tag", "Text" and "EndTag" methods are all extension methods for the HtmlTextWriter-class, this means that they're nothing more than static methods and they do not present any runtime overhead (memory wise at least, they do create an extra call on the stack).

Attributes

One of the most counter intuitive features of the HtmlTextWriter is that you specify attributes of a tag before you create the tag, to remedy that I created an overload of the Tag-extension where the second parameter is a delegate that takes an argument of the type HtmlAttributeManager. An HtmlAttributeManager is just a simple class that wraps an HtmlTextWriter to provide an interface for adding attributes fluently:

public static void Example(HtmlTextWriter writer)
{ 
    // All attributes can be set via the indexer that takes
    // the type of attribute to set and the value for it:
    writer.Tag(HtmlTextWriterTag.Div, e => e[HtmlTextWriterAttribute.Id, "id"]);

    // The indexer returns the HtmlAttributeManager-instance so calls
    // can be chained like this:
    writer.Tag(HtmlTextWriterTag.Div, e => e[HtmlTextWriterAttribute.Id, "id"][HtmlTextWriterAttribute.Name, "name"]);

    // Some common attributes can be set through named methods:
    writer.Tag(HtmlTextWriterTag.Div, e => e.Id("id").Name("name"));

    // Note that those calls can be chained to, you can even mix
    // calls to the indexer and the named methods like this:
    writer.Tag(HtmlTextWriterTag.Div, e => e.Id("id")[HtmlTextWriterAttribute.Title, "Lorem ipsum."].Class("class"));
}

Let's have a look at how the syntax looks for a little longer html-snippet, here I render the same html, first by a static string, and the via the fluent interface:

public void RenderUsingString(HtmlTextWriter writer)
{
    var html = @"
    <div class=""someClass someOtherClass"">
        <h1>Lorem</h1>
        <select id=""fooSelect"" name=""fooSelect"" class=""selectClass"">
            <option value=""1"" title=""Selects the number 1."">1</option>
            <option value=""2"" title=""Selects the number 2."">2</option>
            <option value=""3"" title=""Selects the number 3."">3</option>
        </select>
    </div>
    ";

    writer.Write(html);
}

public void RenderusingExtensionMethods(HtmlTextWriter writer)
{
    writer
        .Tag(HtmlTextWriterTag.Div, a => a.Class("someClass", "someOtherClass"))
            .Tag(HtmlTextWriterTag.H1).Text("Lorem").EndTag()
            .Tag(HtmlTextWriterTag.Select, t => t.Id("fooSelect").Name("fooSelect").Class("selectClass"))
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "1"][HtmlTextWriterAttribute.Title, "Selects the number 1."])
                    .Text("1")
                .EndTag(HtmlTextWriterTag.Option)
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "2"][HtmlTextWriterAttribute.Title, "Selects the number 2."])
                    .Text("2")
                .EndTag(HtmlTextWriterTag.Option)
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "3"][HtmlTextWriterAttribute.Title, "Selects the number 3."])
                    .Text("3")
                .EndTag(HtmlTextWriterTag.Option)
            .EndTag(HtmlTextWriterTag.Select)
        .EndTag(HtmlTextWriterTag.Div);
}

Now that's a lot more readable than the same code would've been using the normal way of rendering with the HtmlTextWriter, actually, let's have a look at how that would look.

public void RenderUsingHtmlTextWriterStandardMethods(HtmlTextWriter writer)
{
   writer.AddAttribute(HtmlTextWriterAttribute.Class, "someClass someOtherClass");
   writer.RenderBeginTag(HtmlTextWriterTag.Div);

   writer.RenderBeginTag(HtmlTextWriterTag.H1);
   writer.Write("Lorem");
   writer.RenderEndTag();

   writer.AddAttribute(HtmlTextWriterAttribute.Id, "fooSelect");
   writer.AddAttribute(HtmlTextWriterAttribute.Name, "fooSelect");
   writer.AddAttribute(HtmlTextWriterAttribute.Class, "selectClass");
   writer.RenderBeginTag(HtmlTextWriterTag.Select);

   writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
   writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 1.");
   writer.RenderBeginTag(HtmlTextWriterTag.Option);
   writer.Write("1");
   writer.RenderEndTag();

   writer.AddAttribute(HtmlTextWriterAttribute.Value, "2");
   writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 2.");
   writer.RenderBeginTag(HtmlTextWriterTag.Option);
   writer.Write("2");
   writer.RenderEndTag();

   writer.AddAttribute(HtmlTextWriterAttribute.Value, "3");
   writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 3.");
   writer.RenderBeginTag(HtmlTextWriterTag.Option);
   writer.Write("3");
   writer.RenderEndTag();

   writer.RenderEndTag();

   writer.RenderEndTag();
}

The code produced when using the fluent interface is a lot closer to the end result, the html code, so it's a lot easier to decipher (read), which means that it's  lot more maintainable.

I've also added some functionality for simple data binding and repeating, more about that next time.