I developed a habit a few years ago (and it escapes me where I first saw it used) of extending my Business Objects with little display helpers for easily serializing them into web pages and email templates. At first, I was just overriding .ToString(), but that never really felt like the right place for it since more often than not it was rending HTML and not plain text which I found to be less than intuitive. Therefore, those many of my objects ended up with a little AsHtml() method that looked something tlike this:
1: public string AsHtml()
2: {
3: StringBuilder sb = new StringBuilder();
4:
5: using (StringWriter sw = new StringWriter(sb))
6: {
7: using (HtmlTextWriter writer = new HtmlTextWriter(sw))
8: {
9: /// Render the object
10: }
11: sw.Flush();
12: }
13:
14: return sb.ToString();
15: }
Lately, the more I see those littered around, the more uncomfortable I feel about it from a Separation of Concerns (SoC) perspective. Essentially, it comes done to this simple question: Why does my Order class (for instance) need to know how to render itself as HTML? When that library gets reused, for instance, in a WCF Service getting consumed by WinForms or Silverlight or what have you, those end points generally don’t need that information and it’s just bloating the POCO getting passed around.
So, simple solution: move the rendering code up the stack much closer to where it’s needed. However, I still want it to be reusable – it’d be silly to have to re-code (or copy and paste) the rendering logic every time I need it. At first, I figured I’d just create a nice little DisplayHelper class with static methods that took the objects and spit back the rendered object. It was simple solution and very easy to implement – I just had to replace Object.AsHtml() with DisplayHelper.RenderHtml(Object object);
Then it dawned on me that I could have my cake and eat it too! I really like the simple dot notation syntax of just saying object.ToHtml() but how do we get that without bloating the objects? Simple answer – The shiny goodness of Extension Methods added in .NET 3.0. By taking the DisplayHelper class, making it static and passing the object with the “this” keyword, we can automatically make that method available to all objects of that type. Now, we’ve removed the bloat from the object, moved the rendering up the stack where it belongs and still employed that nice dot notation. Now, our helper looks like this:
1: public static class DisplayHelper
2: {
3:
4: public static string AsHtml(this Order order)
5: {
6: StringBuilder sb = new StringBuilder();
7:
8: using (StringWriter sw = new StringWriter(sb))
9: {
10: using (HtmlTextWriter writer = new HtmlTextWriter(sw))
11: {
12: /// Render the passed in object
13: }
14: sw.Flush();
15: }
16:
17: return sb.ToString();
18: }
19:
20: }
Now, anywhere in the web project we see an Order, we can use the simple Order.AsHtml() statement just like before!