Thursday, July 30, 2009

Using a builder like pattern with MVC Helper Methods

The Microsoft MVC framework is a powerful new technology but after some work I found the helper extension methods to be a little restrictive. While creating copious methods with overloads it dawned on me a string builder like pattern could be used
Here is a pseudo code example what was implemented.


//Example of builder class
using System.Web.Mvc;
public class InlineTagBuilder : TagBuilder, IHelperBuilder
where T : InlineTagBuilder
{
public InlineTagBuilder(HtmlHelper helper, string tagName, TagRenderMode mode)
: base(tagName)
{

Helper = helper;
Mode = mode;
}

protected TagRenderMode Mode { get; private set; }

public HtmlHelper Helper { get; private set; }

new public T AddCssClass(string value)
{
base.AddCssClass(value);
return (T)this;
}

new public T MergeAttribute(string key, string value, bool replaceExisting)
{
base.MergeAttribute(key, value, replaceExisting);
return (T)this;
}

new public T MergeAttribute(string key, string value)
{
base.MergeAttribute(key, value, false);
return (T)this;
}

new public T MergeAttributes(IDictionary attributes, bool replaceExisting)
{
base.MergeAttributes(attributes, replaceExisting);
return (T)this;
}

new public T MergeAttributes(IDictionary attributes)
{
base.MergeAttributes(attributes, false);
return (T)this;
}

new public T SetInnerText(string innerText)
{
base.SetInnerText(innerText);
return (T)this;
}

public T AppendAttributeValue(string key, string right)
{
string left;
if (Attributes.TryGetValue(key, out left))
{
Attributes[key] = String.Concat(left, right);
}
else
{
Attributes.Add(key, right);
}
return (T)this;
}

public T InsertAttributeValue(string key, string left)
{
string right;
if (Attributes.TryGetValue(key, out right))
{
Attributes[key] = String.Concat(left, right);
}
else
{
Attributes.Add(key, left);
}
return (T)this;
}

public T AppendEvent(string name, string body)
{
return AppendAttributeValue(name, body);
}

public T InsertEvent(string name, string body)
{
return InsertAttributeValue(name, body);
}

public T AppendStyle(string value)
{
if (value != null && !value.EndsWith(";"))
{
value = String.Concat(value, ';');
}
return AppendAttributeValue("style", value);
}

public T SetId(string id)
{
return MergeAttribute("id", id, true);
}

public T SetTitle(string title)
{
return MergeAttribute("title", title, true);
}

public T SetInnerHtml(string innerHtml)
{
base.InnerHtml = innerHtml;
return (T)this;
}

public static implicit operator string(InlineTagBuilder builder)
{
return builder.ToString(builder.Mode);
}
}
public class AnchorTagBuilder : InlineTagBuilder
{
//Anchor Set Methods Here Each Method Returns This For Inline Stacking Of Method Calls...
}
//Add extension class for easy access from the helper in the view
public static class AnchorTagBuilderExtensions
{
public static AnchorTagBuilder Anchor(this HtmlHelper helper)
{
return new AnchorTagBuilder(helper);
}
}
//Example of what the view would look like
<html>
<body>

<%=Html.Anchor().MergeAttribute("href","http://www.microsoft.com").AddCssClass("footNote").AppendEvent("onclick","alert('Really Annoying Alert Box!')") %>

</body>
</html>

No comments:

Post a Comment