<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.9.2 (http://www.squarespace.com/) on Fri, 12 Mar 2010 11:24:12 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><title>KevinRohrbaugh.com</title><subtitle>Blog</subtitle><id>http://www.kevinrohrbaugh.com/blog/</id><link rel="alternate" type="application/xhtml+xml" href="http://www.kevinrohrbaugh.com/blog/"/><link rel="self" type="application/atom+xml" href="http://www.kevinrohrbaugh.com/blog/atom.xml"/><updated>2010-03-11T03:20:54Z</updated><generator uri="http://www.squarespace.com/" version="Squarespace Site Server v5.9.2 (http://www.squarespace.com/)">Squarespace</generator><entry><title>VMware ESXi Is Awesome (and Free)</title><category term="Ramblings"/><category term="Virtualization"/><category term="esxi"/><id>http://www.kevinrohrbaugh.com/blog/2010/3/2/vmware-esxi-is-awesome-and-free.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2010/3/2/vmware-esxi-is-awesome-and-free.html"/><author><name>Kevin Rohrbaugh</name></author><published>2010-03-02T05:52:29Z</published><updated>2010-03-02T05:52:29Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><em>First a disclaimer:</em> This post is mainly geek porn for myself. Since most of the content below has been captured <a href="http://vm-help.com/">elsewhere</a>, it’s not really adding anything new to the corpus of ESXi knowledge on the Internet. Oh well.</p>  <h2>Why Am I Doing This?</h2>  <p>Throughout my career, I’ve always worked at organizations large enough that systems administration and IT operations were handled by a different group from the development organization. I have always been on the development side of the fence, which means I run into basic sysadmin work from time to time but my first-hand knowledge is limited. In an attempt to fix this (and satisfy my need to buy new hardware constantly), I decided to buy a beefy home server to run <a href="http://www.vmware.com/products/esxi/">VMware ESXi</a> on.</p>  <p>If you haven’t heard of ESXi, it is a <em>free</em> (as in beer) bare metal <a href="http://en.wikipedia.org/wiki/Hypervisor">hypervisor</a>, which basically means it runs virtual machines without the need for a traditional host OS. Essentially, I can setup multiple virtualized servers on one physical server and learn as much about systems administration as I’d like.</p>  <h2>The Machine</h2>  <p>Using the excellent unofficial <a href="http://vm-help.com/esx40i/Hardware_support.php">hardware compatibility lists</a> on <a href="http://vm-help.com/">Dave Mishchenko’s vm-help site</a>, I spent a bunch of time sorting out whether I wanted to build a machine or buy a <a href="http://www.vm-help.com//esx40i/esx40_whitebox_HCL.php">whitebox server</a>. Eventually, a sale on Dell’s Small Business site led me to decide that the whitebox option was the way to go. I ordered a Dell PowerEdge T110 with the following configuration details and costs:</p>  <ul>   <li><a href="http://www.dell.com/us/en/business/servers/poweredge-t110/pd.aspx?refid=poweredge-t110&amp;s=bsd&amp;cs=04">Dell PowerEdge T110</a> - $1300</li>    <ul>     <li>Processor: X3440 (Lynnfield) Xeon, 2.53GHz, 8MB L3 Cache, Quad-Core with Hyper-Threading</li>      <li>RAM: 16GB (4x4GB) 1333MHz, Dual Ranked UDIMM</li>      <li>Network Adapter: On board</li>      <li>RAID Controller: None</li>      <li>Storage (HDD): <a href="http://www.tkqlhce.com/click-3844611-10440897?url=http%3A%2F%2Fwww.newegg.com%2FProduct%2FProduct.aspx%3FItem%3DN82E16822148337%26nm_mc%3DAFC-C8Junction%26cm_mmc%3DAFC-C8Junction-_-Hard%2BDrives-_-Seagate-_-22148337&cjsku=N82E16822148337" target="_top" onmouseover="window.status='http://www.newegg.com';return true;" onmouseout="window.status=' ';return true;">
4x 1.5TB/7200RPM Seagate Barracuda OEM drives (6TB)</a><img src="http://www.ftjcfx.com/image-3844611-10440897" width="1" height="1" border="0"/> - $330</li>      <li>Storage (Flash): <a href="http://www.dpbolvw.net/click-3844611-10440897?url=http%3A%2F%2Fwww.newegg.com%2FProduct%2FProduct.aspx%3FItem%3DN82E16820220252%26nm_mc%3DAFC-C8Junction%26cm_mmc%3DAFC-C8Junction-_-Memory%2B%28USB%2BFlash%2BDrive%29-_-Patriot%2BMemory-_-20220252&cjsku=N82E16820220252" target="_top" onmouseover="window.status='http://www.newegg.com';return true;" onmouseout="window.status=' ';return true;">
Patriot Xporter XT Boost 8GB Flash Drive</a><img src="http://www.ftjcfx.com/image-3844611-10440897" width="1" height="1" border="0"/> - $25</li>   </ul> </ul>  <p>Total cost ended up being just shy of $1655, including shipping. Note that I cheated a bit because I already had one 1.5TB Barracuda that I had picked up for this project at a recent <a href="http://www.microcenter.com/">Microcenter</a> sale so its purchase price isn’t included. Through NewEgg, the fourth drive would add about $120 more for a grand total of $1775.</p>  <p>While $1800 is not exactly cheap, 16GB of RAM and 6TB of drive space is a bit excessive, so it’d be possible to build a more reasonable config for quite a bit less. The biggest downfall for this setup is the lack of RAID, so my 4x 1.5TB drives are four discrete drives within ESXi (<a href="http://en.wikipedia.org/wiki/JBOD#JBOD">JBOD</a>). Not a huge deal to me, but not ideal, admittedly.</p>  <h2>Putting It All Together</h2>  <p>The process of putting all the pieces together was pretty mundane, with the only real delighter being the two internal USB ports on the T110’s motherboard. Since my plan was to install ESXi on the USB flash drive, this allowed me to avoid having it stick out the back of the machine permanently. Overall, the internal design of the T110 is nice. The rest was uneventful, so I won’t bore you with details; only pictures!</p>  <p align="center"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="6TB of Awesome!" border="0" alt="6TB of Awesome!" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-MeetKermitMyESXiHomeServer_148CD-?fileId=5969522" width="244" height="244" /> <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Internal USB with 8GB Boot Disk" border="0" alt="Internal USB with 8GB Boot Disk" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-MeetKermitMyESXiHomeServer_148CD-?fileId=5969523" width="244" height="244" /> </p>  <h2>The Setup Process</h2>  <p>I went into the ESXi setup process thinking it was going to be this big battle that would take me all weekend. It actually took about an hour, and was so straight-forward I was kind of disappointed. This is all I did:</p>  <ul>   <li>Downloaded and burned the ESXi 4.0 Update 1 Dell Customized ISO from <a href="http://www.vmware.com/products/esxi/">VMware</a></li>    <li>Enabled “Virtualization Technology” under “Processor Settings” in the T110’s BIOS to turn on <a href="http://www.intel.com/technology/virtualization/">Intel’s VT-x</a></li>    <li>Changed boot order to flash drive first (the USB drive was recognized by BIOS without issue)</li>    <li>Installed ESXi 4 U1 from the disc to the flash drive, which the installer saw as a drive without any changes</li> </ul>  <p>That’s really all there was to it. Based on VMware forum posts, this process was <a href="http://www.vm-help.com/forum/viewtopic.php?p=4302#p4302">harder</a> before Update 1 of ESXi 4, but it’s pleasantly uneventful now.</p>  <h2>Creating Servers</h2>  <p><a href="http://en.wikipedia.org/wiki/Statler_and_Waldorf"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="Statler &amp; Waldorf from The Muppet Show" border="0" alt="Statler &amp; Waldorf from The Muppet Show" align="right" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-MeetKermitMyESXiHomeServer_148CD-?fileId=5969470" width="244" height="166" /></a> Once ESXi booted up, I was able to configure TCP/IP and host name settings using the text-based menu system on the machine. I christened the new box kermit (all my PCs are named after <a href="http://en.wikipedia.org/wiki/The_Muppet_Show">Muppets</a>) and then installed the <a href="http://www.petri.co.il/managing-esxi4-with-vsphere-client.htm">VMware vSphere client</a> on my main Windows 7 machine to finish configuration settings and start making virtual machines. I ran into some issues <a href="http://drewsrambling.blogspot.com/2008/10/esxi-copy-vm-poor-mans-template.html">cloning</a> my base Windows Server 2008 R2 VM, but due to the length of this post, I’ll leave the details for another day. </p>  <p>So far, I’ve got primary and secondary Active Directory controllers (affectionately named <a href="http://en.wikipedia.org/wiki/Statler_and_Waldorf">statler and waldorf</a>), along with the accompanied DNS servers, running my home network name resolution. Unified logins and not having to mess with IP addresses or <em>hosts</em> files is pretty cool. </p>  <h2>Was It Worth It?</h2>  <p>With two servers performing networking duties and a third ready for configuration, I can easily say I’ve learned more about running servers in the past two weeks than I have in the last two years at work. I’ve had the need to dig into <a href="http://technet.microsoft.com/en-us/sysinternals/default.aspx">sysinternals</a> a few times, learned quite a bit about Active Directory and was up until 3AM one night reading about <a href="http://en.wikipedia.org/wiki/List_of_DNS_record_types">DNS record types</a>. I’m still not an expert, and probably never will be with such a small network to manage, but I’ve been having a ton of fun along the way. It’s been an effective learning tool for me so far, and I’m just getting started with what I want to do.</p>  <p>In fact, ESXi is one of the coolest things I’ve played with in quite a while, so my only regret is that I didn’t look into it sooner. </p>]]></content></entry><entry><title>Adrenaline Junkies and Template Zombies</title><category term="Books"/><category term="project-management"/><id>http://www.kevinrohrbaugh.com/blog/2009/12/4/adrenaline-junkies-and-template-zombies.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/12/4/adrenaline-junkies-and-template-zombies.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-12-04T18:00:13Z</published><updated>2009-12-04T18:00:13Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>I&rsquo;m a big fan of patterns, as I find that codebases employing well-known patterns (such as MVC) are much more approachable for developers new to a project, making them easier to maintain over their lifetime. Of course, patterns aren&rsquo;t limited to just code, but are also found and applied in other fields, from architecture to medicine, because they help quickly communicate a shared understanding of a situation or approach. This allows discourse to more quickly move to the relevant bits, rather than just getting up to speed.</p>
<p><img style="margin: 0px 0px 0px 5px; display: inline;" src="http://ecx.images-amazon.com/images/I/51JlFQRdMkL._SL160_.jpg" alt="" align="right" /></p>
<p>My predisposition to patterns is one reason I enjoyed <a href="http://www.amazon.com/Adrenaline-Junkies-Template-Zombies-Understanding/dp/0932633676%3FSubscriptionId%3D0JTCV5ZMHMF7ZYTXGFR2%26tag%3Dkevinrohrcom-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0932633676">Adrenaline Junkies and Template Zombies: Understanding Patterns of Project Behavior</a> by Tom DeMarco, Peter Hruschka, Tim Lister, Steve McMenamin, James Robertson and Susan Robertson.</p>
<p>If you don&rsquo;t recognize those names, it&rsquo;s the <a href="http://www.systemsguild.com/">Atlantic Systems Guild</a>, the same group of people that wrote <a href="http://www.amazon.com/gp/product/0932633439?ie=UTF8&amp;tag=kevinrohrcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0932633439">Peopleware</a>. In Adrenaline Junkies and Template Zombies, the guild outlines common project and organizational patterns that they&rsquo;ve observed throughout their careers. Many of the patterns tend to be anti-patterns, rather than traditional patterns you would want to emulate. This is also why so much of the book struck me as humorous, if only because they may be familiar from your own experience.</p>
<p>My favorite pattern in the book happens to be the first one, which is Adrenaline Junkies. From the book:</p>
<blockquote>
<p>You probably recognize the characteristics of the adrenaline junkie organization: Priorities are constantly shifting; everything is needed &ldquo;yesterday;&rdquo; there&rsquo;s never enough project time before delivery; every project is urgent; and the urgent projects just keep coming. Everybody is frantically busy . . . all the time.</p>
<p>People in these organizations do not think strategically. Work gets done on the basis of its urgency alone. Unless a project&rsquo;s &ldquo;frantic factor&rdquo; is high, it will be ignored &ndash; even though it promises a significant long-term advantage. It will remain ignored until it suddenly (surprise, surprise) becomes urgent. Adrenaline junkies believe that the best way to work is not by planning but by running as fast as possible.</p>
</blockquote>
<p><a href="http://www.flickr.com/photos/jesuspresley/196500068/"><img style="display: inline; margin-left: 0px; margin-right: 0px; border: 0px;" title="BMX rider jumping through the air - Photo by: Jesus Presley (Flickr)" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-AdrenalineJunkiesTemplateZombies_9D1B-?fileId=4966544" border="0" alt="BMX rider jumping through the air - Photo by: Jesus Presley (Flickr)" width="244" height="184" align="right" /></a> Most of us have probably seen individuals, teams or entire organizations exhibiting this behavior. It&rsquo;s all too often to find an adrenaline junkie developer, as they tend to be the types who see their entire job as the act of <em>writing code</em>. If they aren&rsquo;t writing code, they&rsquo;re wasting time, since planning, design and research are more strategic actions and not directly related to that urgent bit of deliverable they&rsquo;ve just been asked for. The pattern even highlights the fact that adrenaline junkie organizations tend to &ldquo;enthusiastically embrace the customer service ethic: They confuse responding to urgency with admirable responsiveness.&rdquo; The truth, of course, is that treating all requests equally based only on urgency, without thinking about the larger value (or even usefulness), is actually a disservice to your customer.</p>
<p>The book&rsquo;s goal is to capture and identify common patterns, and there are dozens of other patterns which are equally interesting. It only glosses over what can be done to fix projects or teams that exhibit anti-patterns, but understanding the behavior is the first step to addressing it in any event. It&rsquo;s a good read that is likely to give you a better understanding for behavior you may encounter during your career, while also entertaining you. If you&rsquo;re at all interested in the soft skill side of IT project work, I recommend checking it out.</p>]]></content></entry><entry><title>When It Comes to Unit Tests, Names Are Important</title><category term="Testing"/><id>http://www.kevinrohrbaugh.com/blog/2009/11/11/when-it-comes-to-unit-tests-names-are-important.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/11/11/when-it-comes-to-unit-tests-names-are-important.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-11-11T19:00:47Z</published><updated>2009-11-11T19:00:47Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Like many developers, when I first started writing unit tests, I didn&rsquo;t approach it with much discipline. It&rsquo;s just test code, after all; no user is going to look at it. This led me to write test methods like this:</p>
<pre class="brush: csharp;">[Test]
public void IdTest()
{
    // Test code here
}</pre>
<p>It&rsquo;s easy to see how woefully inadequate this naming structure is, not to mention that appending &ldquo;Test&rdquo; to the end of every test method (when it already has an attribute declaring as much) is obnoxious. When I wrote unit tests like this, I typically used my unit tests (which often ended up actually being integration tests) only until I had a functional UI and then reverted to browser-based manual testing.</p>
<p>Flash forward to the present, where I make sure that all my unit test methods are named using a pattern that I&rsquo;ve picked up from the likes of <a href="http://weblogs.asp.net/ROsherove/">Roy Osherove</a> and others:</p>
<pre class="brush: csharp;">[Test]
public void MethodUnderTest_ExpectedResult_GivenCondition()
{
    // Test code here
}</pre>
<p>Using this convention, each part of the test method name carries specific information:</p>
<ul>
<li><span style="font-family: 'Lucida Console';">MethodUnderTest</span>: Specifies what method of the test class we&rsquo;re exercising, scoping the test to a specific aspect of the class being tested.</li>
<li><span style="font-family: 'Lucida Console';">ExpectedResult</span>: Specifies what the test expects the results of calling the <span style="font-family: 'Lucida Console';">MethodUnderTest</span> should be and scopes what our asserts for the test will be checking.</li>
<li><span style="font-family: 'Lucida Console';">GivenCondition</span>: Outlines the environmental or argument conditions that the test should run within. </li>
</ul>
<p>All three elements of this naming structure help to tightly define what it is that the test should be doing. This is critical as the primary consumer of unit tests is almost always the future developer, not the present one. In other words, we write unit tests to help us today, but a lot of their benefit comes when we make changes to the application in the future and can prove that individual components still work after those changes are implemented. If you&rsquo;re like most people, using a test method naming convention that serves as a cheat sheet for what you were thinking when you wrote the test six months ago will come in handy and help make sure you preserve the intent of that test if/when it starts to fail.</p>
<p>Here&rsquo;s an example of a real unit test using the naming convention:</p>
<pre class="brush: csharp;">[Fact]
public void Go_RedirectsToIndex_WithEmptySearchTerm()
{
    var searchTerms = string.Empty;

    var result = Controller.Go(searchTerms);

    var actionName =
        result.AssertActionRedirect().RouteValues["action"].ToString();
    Assert.Equal("Index", actionName, StringComparer.InvariantCultureIgnoreCase);
}</pre>
<p>It seems like such a simple thing to adhere to, but it&rsquo;s made a world of difference in my test maintainability. It&rsquo;s even made it easier to write tests, since the naming convention makes me think critically about what I&rsquo;m trying to test. It&rsquo;s great when a little change like this makes such a big impact on my day-to-day development.</p>]]></content></entry><entry><title>Do Yourself a Favor: Read ASP.NET MVC In Action</title><category term="ASP.NET MVC"/><category term="Books"/><id>http://www.kevinrohrbaugh.com/blog/2009/11/5/do-yourself-a-favor-read-aspnet-mvc-in-action.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/11/5/do-yourself-a-favor-read-aspnet-mvc-in-action.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-11-05T18:30:36Z</published><updated>2009-11-05T18:30:36Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Up until recently, my favorite ASP.NET MVC book has been <a href="http://www.amazon.com/gp/product/1430210079?ie=UTF8&amp;tag=kevinrohrcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1430210079">Pro ASP.NET MVC Framework</a> by Steven Sanderson. It goes a lot deeper in the framework than <a href="http://www.amazon.com/gp/product/0470384611?ie=UTF8&amp;tag=kevinrohrcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0470384611">Professional ASP.NET MVC 1.0</a> (aka the NerdDinner book) and provides good coverage to important topics like unit testing and model binders. It&rsquo;s a rather good book for those serious about diving into MVC.</p>
<p>Now I&rsquo;m adding <a href="http://www.amazon.com/gp/product/1933988622?ie=UTF8&amp;tag=kevinrohrcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1933988622">ASP.NET MVC in Action</a>, by Jeff Palermo, Ben Scheirman and Jimmy Bogard to my recommended reading list for serious MVC developers.</p>
<p align="center"><img src="http://ecx.images-amazon.com/images/I/51EJtErAQ6L._SL160_.jpg" alt="" /> <br /><a href="http://www.amazon.com/ASP-NET-MVC-Action-Jeffrey-Palermo/dp/1933988622%3FSubscriptionId%3D0JTCV5ZMHMF7ZYTXGFR2%26tag%3Dkevinrohrcom-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1933988622">ASP.NET MVC in Action</a></p>
<p>If you&rsquo;re already familiar with unit testing or tools like dependency injection, it&rsquo;s probably safe to skip Sanderson&rsquo;s tome and just dive into Palermo&rsquo;s. The book does a good job of quickly covering the basics of MVC, then moves on to more advanced topics, such as customization points within the framework, refactoring components that are likely to get bloated, best practices (including use of <a href="http://www.mvccontrib.org/">MvcContrib</a>), some recipes and even a chapter on MonoRail and Ruby on Rails. Throughout all of these sections, the pace is brisk, covering a lot of ground without an obvious intent to bulk up the page count. I love it when authors respect my time and intelligence more than the publisher&rsquo;s wish to ship a thousand page boat anchor.</p>
<p>What I like best about the book is that it&rsquo;s not built from the perspective of Redmond isolationism and actually acknowledges other communities, tools and approaches, while still staying targeted at the ASP.NET MVC developer crowd. There should be more books like this.</p>
<p>All that said, it&rsquo;s more advanced than the other books, so if you never played around with the MVP pattern in Web Forms, haven&rsquo;t ever written a unit test and don&rsquo;t know what DI stands for, you&rsquo;ll still want to start with the <a href="http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx">NerdDinner sample</a> (skip the rest), then read Sanderson&rsquo;s book before jumping into <a href="http://www.amazon.com/gp/product/1933988622?ie=UTF8&amp;tag=kevinrohrcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1933988622">In Action</a>.</p>]]></content></entry><entry><title>The Stereotyping of Designers &amp; Developers</title><category term="Ramblings"/><id>http://www.kevinrohrbaugh.com/blog/2009/10/30/the-stereotyping-of-designers-developers.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/10/30/the-stereotyping-of-designers-developers.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-10-30T18:00:28Z</published><updated>2009-10-30T18:00:28Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>A few weeks ago, I attended a talk given by <a href="http://en.wikipedia.org/wiki/Daniel_pink">Daniel Pink</a>, who frequently speaks about the&nbsp; value of &ldquo;right-brain&rdquo; thinking and its increasing importance in the future (see his book, <a href="http://www.amazon.com/gp/product/1594481717?ie=UTF8&amp;tag=kevinrohrcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1594481717">A Whole New Mind: Why Right-Brainers Will Rule the Future</a>). By right-brain, he typically means creative thinking skills, or the ability to identify patterns in less-than-obvious situations. In case you haven&rsquo;t seen it, the talk he gave at TED will give a better flavor about his main points:</p>
<p align="center"><object width="446" height="326"><param name="movie" value="http://video.ted.com/assets/player/swf/EmbedPlayer.swf"></param><param name="allowFullScreen" value="true" /><param name="wmode" value="transparent"></param><param name="bgColor" value="#ffffff"></param> <param name="flashvars" value="vu=http://video.ted.com/talks/dynamic/DanielPink_2009G-medium.flv&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/DanielPink-2009G.embed_thumbnail.jpg&amp;vw=432&amp;vh=240&amp;ap=0&amp;ti=618&amp;introDuration=16500&amp;adDuration=4000&amp;postAdDuration=2000&amp;adKeys=talk=dan_pink_on_motivation;year=2009;theme=not_business_as_usual;theme=the_creative_spark;theme=new_on_ted_com;theme=speaking_at_tedglobal2009;event=TEDGlobal+2009;&amp;preAdTag=tconf.ted/embed;tile=1;sz=512x288;" /><embed src="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" pluginspace="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent" bgColor="#ffffff" width="446" height="326" allowFullScreen="true" flashvars="vu=http://video.ted.com/talks/dynamic/DanielPink_2009G-medium.flv&su=http://images.ted.com/images/ted/tedindex/embed-posters/DanielPink-2009G.embed_thumbnail.jpg&vw=432&vh=240&ap=0&ti=618&introDuration=16500&adDuration=4000&postAdDuration=2000&adKeys=talk=dan_pink_on_motivation;year=2009;theme=not_business_as_usual;theme=the_creative_spark;theme=new_on_ted_com;theme=speaking_at_tedglobal2009;event=TEDGlobal+2009;"></embed></object></p>
<p>I tend to agree with many of Mr. Pink&rsquo;s core ideas, but during the talk I attended, he mentioned &ldquo;computer programming&rdquo; several times as one of those tasks that&rsquo;s more routine than creative, which is why it has proven to be easy to out-source. Here I disagree, as the creative part of software development tends to be my favorite aspect to the work. Given all the problems a typical software project encounters, it&rsquo;s always surprising when people view development as a formulaic factory where requirements go in one end and software comes out the other.</p>
<p>Of course, it&rsquo;s not just business authors who sometimes miss the boat on the creative parts of software development. Microsoft itself went through a phase of cranking out &ldquo;software factory&rdquo; patterns. More recently, they also seem to have latched on to right-brain/left-brain segmentation, as best seen with the <a href="http://www.microsoft.com/expression/">Expression</a> line of products.</p>
<p>It&rsquo;s great for Microsoft to enter and compete in a market that is utterly dominated by Adobe, but they also seem overly eager to target WPF and Silverlight UI development at the &ldquo;creatives,&rdquo; eschewing their traditional strong-hold of &ldquo;<a href="http://www.youtube.com/watch?v=8To-6VIJZRE">developers, developers, developers</a>&rdquo;. This seems like a risky strategy that has contributed to the lukewarm adoption of both of these technologies. Designers have been building things using Adobe products for years, so getting them to switch isn&rsquo;t likely to happen overnight. Meanwhile, Microsoft developers are almost constantly being told that WPF is awesome, but it&rsquo;s intended for designer/developer teams. Unfortunately, there are an awful lot of development teams (such as those building line-of-business apps) without dedicated design staff, making this messaging and strategy a non-starter.</p>
<p>We humans are just starting to understand how our brains work and the entire notion of &ldquo;right-brain people&rdquo; might turn out to be a modern <a href="http://en.wikipedia.org/wiki/Phrenology">phrenology</a>. There are many aspects to development that require creativity, just as there are many aspects to design that are analytical. It&rsquo;s best to judge people based on their actual performance and contributions, rather than a role-based notion of right- or left-brain preference. After all, if developers were all total left-brain people, they would have left for <a href="http://en.wikipedia.org/wiki/Vulcan_%28Star_Trek%29">Vulcan</a> a while ago, and if designers were all right-brain, <a href="http://en.wikipedia.org/wiki/ActionScript">ActionScript</a> would be a lot less popular.</p>]]></content></entry><entry><title>Breaking Bad Habits: Views &amp; Data</title><category term="ASP.NET MVC"/><category term="asp.net mvc"/><category term="separation of concerns"/><id>http://www.kevinrohrbaugh.com/blog/2009/10/23/breaking-bad-habits-views-data.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/10/23/breaking-bad-habits-views-data.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-10-23T17:30:22Z</published><updated>2009-10-23T17:30:22Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><a href="http://www.flickr.com/photos/hmvh/3336771374/"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="A pile of cigarette butts - Photo by: hmvh (Flickr)" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-BreakingBadHabitsViewsData_5D7-?fileId=4532245" border="0" alt="A pile of cigarette butts - Photo by: hmvh (Flickr)" width="244" height="244" align="right" /></a> The fact that ASP.NET MVC&rsquo;s default view engine is built on top of Web Forms brings a lot of advantages, key among them being familiarity for existing ASP.NET developers. The bee-sting notation (<span style="font-family: 'Lucida Console';">&lt;%= %&gt;</span>) has been around for quite a while and a lot of the code you put inside it looks pretty familiar to Microsoft&rsquo;s web developer crowd.</p>
<p>The drawback to this familiarity is that it&rsquo;s easy to start using Web Form-based development habits within your views, especially around the sourcing and retrieval of data. This can cause maintainability issues because views are one of the hardest parts of an application to accurately and robustly test. Lots of testing products exist, along with tools like <a href="http://seleniumhq.org/">Selenium</a> and <a href="http://watin.sourceforge.net/">WatiN</a>, but it&rsquo;s hard enough to get applications to look and work consistently across different browsers, let alone build a holistic and resilient UI test suite. That&rsquo;s why it&rsquo;s so important to keep your views clean and devoid of all but the simplest logic.</p>
<p>A common pitfall when moving to MVC is to not rely on the framework&rsquo;s methods for passing data from controllers to the view. For instance, in Web Forms-based applications, it&rsquo;s not all that uncommon for ASPX pages to go digging around in session state for data. In an MVC application, however, this is a violation of <a href="http://en.wikipedia.org/wiki/Separation_of_concerns">separation of concerns</a>, as the view now possesses knowledge for where data is being stored (or at least cached), and is bypassing the controller&rsquo;s sovereign rights to provide the view with all the data that it needs. Remember, <a href="http://www.kevinrohrbaugh.com/blog/2009/9/11/are-your-controllers-playing-music.html">the controller&rsquo;s purpose in life</a> is to orchestrate processing and pass the appropriate data to a view for rendering.</p>
<p>If the view needs data that&rsquo;s stored in the session (or elsewhere) it&rsquo;s the controllers job to retrieve it and provide it through the standard way of transmitting data from controller to view: <a href="http://weblogs.asp.net/scottgu/archive/2007/12/06/asp-net-mvc-framework-part-3-passing-viewdata-from-controllers-to-views.aspx">ViewData</a>. If the view needs a lot of disparate data to perform it&rsquo;s duties, it probably means you&rsquo;re in need of a <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx">view </a><a href="http://www.flickr.com/photos/zigazou76/3702501888/"><img style="border-bottom: 0px; border-left: 0px; margin: 5px 5px 5px 0px; display: inline; border-top: 0px; border-right: 0px" title="Danger sign - Photo by: zigazou76 (Flickr)" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-BreakingBadHabitsViewsData_5D7-?fileId=4532246" border="0" alt="Danger sign - Photo by: zigazou76 (Flickr)" width="244" height="184" align="left" /></a>model object that ties all that data together in a format the view can easily work with. The importance of view model objects shouldn&rsquo;t be overlooked. They are distinct from the domain model classes typically outlined in MVC discussions and are a critical component to building anything more than the simplest MVC application.</p>
<p>This brings us back to why the Web Forms view engine can be a slippery slope, allowing us to fall into the <a href="http://en.wikipedia.org/wiki/Pit_of_despair">pit of despair</a> even though its familiarity makes it <em>seem</em> like the <a href="http://blogs.msdn.com/brada/archive/2003/10/02/50420.aspx">pit of success</a>. Since it, like the rest of ASP.NET MVC, is built on top of ASP.NET you can access all those old properties and objects to poke around directly in session, or even the request, to get values and data the view may need. My advice when those temptations arise is to fight the urge, make sure the controller provides your view with all the data it needs and develop as though you don&rsquo;t have access to such functionality. Your applications will be better off for it.</p>
<p><em><span style="font-size: xx-small;">This post targets Visual Studio 2008 and ASP.NET MVC 1.0 .The content may not be relevant for other product, framework or language versions.</span></em></p>]]></content></entry><entry><title>Getting Outside the Microsoft Echo Chamber</title><category term="Ramblings"/><id>http://www.kevinrohrbaugh.com/blog/2009/10/16/getting-outside-the-microsoft-echo-chamber.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/10/16/getting-outside-the-microsoft-echo-chamber.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-10-16T17:00:53Z</published><updated>2009-10-16T17:00:53Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Several of the ASP.NET MVC books cite the fact that the MVC pattern itself is very old, wasn&rsquo;t created by Microsoft and has been deployed within web applications on other technology stacks for quite some time. Unfortunately, the Microsoft developer community tends to be rather insular, so many developers aren&rsquo;t aware of the work that&rsquo;s occurred in other communities and/or simply aren&rsquo;t interested.</p>
<p><a href="http://www.flickr.com/photos/neldiogo/3248564777/"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="Time-lapsed traffic - Photo by: Nelson D. (Flickr)" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-GettingOutsidetheMicrosoftEchoChamber_A703-?fileId=4460782" border="0" alt="Time-lapsed traffic - Photo by: Nelson D. (Flickr)" width="165" height="244" align="right" /></a>This is a mistake. Since these other communities are rather mature compared to the ASP.NET MVC crowd, they are typically a great place to glimpse a possible future and influences on the Microsoft MVC platform. In other words, Microsoft&rsquo;s late entry into the MVC pattern for web development means that our community should be working to leverage all the knowledge and experience discovered by existing communities, which is especially beneficial since we have a minimal amount of &ldquo;legacy&rdquo; to overcome (both code and thinking).</p>
<p>Of course, there&rsquo;s only so much time in the day and, if you&rsquo;re at all like me, it&rsquo;s a struggle just to keep up with developments in the .NET space, let alone a host of other languages and frameworks. To counter this problem, the approach that I use is to mix in non-.NET podcasts to my daily commute, so that I can at least hear about developments in other communities and follow-up on items that interest me when I get a chance. Here are some of the podcasts that I&rsquo;m currently listening to with this end in mind:</p>
<ul>
<li><a href="http://railsenvy.com/">Rails Envy</a> &ndash; A weekly newscast covering the Ruby on Rails community.</li>
<li><a href="http://www.javaposse.com/">The Java Posse</a> &ndash; A long-standing Java community podcast that discusses a broad cross-section of developments within Java.</li>
<li><a href="http://twit.tv/FLOSS">FLOSS Weekly</a> &ndash; A non-technology specific podcast focusing on any kind of open source software; since it&rsquo;s a Leo Laporte production, it&rsquo;s fairly popular, but is a great way to hear about interesting projects on lesser-known tech stacks.</li>
</ul>
<p>I wouldn&rsquo;t put any of these into the &ldquo;hidden gems&rdquo; category as they are all well-known. Furthermore, I tend to change which specific podcasts I use to eavesdrop on other development communities pretty regularly, so which podcasts you choose is less important than the fact that you get outside .NET land and check out what&rsquo;s going on in other parts of the industry. Doing so with podcasts tends to be a good way to accomplish this with a limited time investment.</p>]]></content></entry><entry><title>Empty ASP.NET MVC 1.0 Project Template</title><category term="ASP.NET MVC"/><category term="asp.net mvc"/><category term="visual studio"/><id>http://www.kevinrohrbaugh.com/blog/2009/10/9/empty-aspnet-mvc-10-project-template.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/10/9/empty-aspnet-mvc-10-project-template.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-10-09T19:16:03Z</published><updated>2009-10-09T19:16:03Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><a href="http://www.flickr.com/photos/laffy4k/174328073/"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="Empty stadium seats - Photo by: laffy4k (Flickr)" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-EmptyASP.NETMVC1.0ProjectTemplate_D529-?fileId=4393585" border="0" alt="Empty stadium seats - Photo by: laffy4k (Flickr)" width="244" height="184" align="right" /></a>The project template that ships with <a href="http://www.asp.net/mvc/">ASP.NET MVC 1.0</a> is nice when you first start using the framework and want to see how things work together. Unfortunately, it can be annoying once you actually start using the framework for real projects. This is because the first thing you typically need to do is delete all the extra stuff the template creates, but you don&rsquo;t want in your project.</p>
<p>After having done this more than a few times, I decided to create my own empty ASP.NET MVC project template with all the stuff I rip out and change already done. This empty MVC template has a few substantive changes:</p>
<ul>
<li>There are no default controllers or views, just folders for their locations.</li>
<li>There are no included JavaScript libraries, jQuery or otherwise. </li>
<li>All the <span style="font-family: 'Lucida Console';">Web.config</span> settings dealing with ASP.NET Ajax have been removed</li>
<li>All the <span style="font-family: 'Lucida Console';">Web.config</span> settings dealing with the profile, role and membership services have been removed</li>
<li>The folder structure for images, Javascript and CSS has been changed to <span style="font-family: 'Lucida Console';">Assets/img/</span>, <span style="font-family: 'Lucida Console';">Assets/js/</span>, and <span style="font-family: 'Lucida Console';">Assets/style/</span>, respectively.</li>
</ul>
<p>The guiding principle here is that every project tends to be a bit different, so starting from scratch is often easiest. The stock <span style="font-family: 'Lucida Console';">Web.config</span> files have a lot of extra stuff in them that may not be all that relevant for a lot of projects, and I&rsquo;d rather add stuff back in than have a bunch of unused boilerplate all the time. Plus, I just don&rsquo;t see much purpose for ASP.NET Ajax at this point in time.</p>
<p>The image, script and style folder change is just personal preference; I don&rsquo;t like having <span style="font-family: 'Lucida Console';">Content</span> and <span style="font-family: 'Lucida Console';">Scripts</span> folders like the standard MVC project template does.</p>
<p>A quick note about testing projects: This template won&rsquo;t prompt you to create a testing project like the standard MVC template does. This is not because I think unit testing is dumb (quite the contrary) but because I tend to use my own project structure for testing projects as well, so I don&rsquo;t have a need for it.</p>
<h3>Installation</h3>
<p>I&rsquo;ve posted my <a href="http://www.kevinrohrbaugh.com/storage/post-data/MvcEmptyWebApplicationProjectTemplatev1.cs.zip">Empty ASP.NET MVC 1.0 project template</a>, if you&rsquo;re interested in using it.</p>
<p>If you&rsquo;ve never <a href="http://msdn.microsoft.com/en-us/library/y3kkate1.aspx">installed a custom template</a> before, it&rsquo;s as easy as copying the zip file to <span style="font-family: 'Lucida Console';">\My Documents\Visual Studio 2008\Templates\ProjectTemplates\Visual C#\</span>. Alternatively, if you want the project to show up under the Web sub-category you can place the zip file in <span style="font-family: 'Lucida Console';">\My Documents\Visual Studio 2008\Templates\ProjectTemplates\Visual C#\</span>Web\.</p>
<p>After copying the file to the correct location, you should see the new project template when you go to create projects within VS:</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="proj-template" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-EmptyASP.NETMVC1.0ProjectTemplate_D529-?fileId=4393586" border="0" alt="proj-template" width="538" height="297" /></p>
<h3>Creation</h3>
<p>If you&rsquo;d like to have a similar project template, but don&rsquo;t like some of the changes I&rsquo;ve made, it&rsquo;s fairly simple to create your own Visual Studio project templates. In fact, all the documentation I used is available on MSDN:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/xkh1wxd8%28VS.80%29.aspx">How to: Create Project Templates</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms185311.aspx">How to: Substitute Parameters in a Template</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/eehb4faa.aspx">Template Parameters</a></li>
</ul>
<p>Additionally, if you&rsquo;d like to look at the standard ASP.NET MVC project template (<span style="font-family: 'Lucida Console';">MvcWebApplicationProjectTemplatev1.cs.zip</span>) you can find it installed to <span style="font-family: 'Lucida Console';"><em>&lt;VisualStudioInstallDirectory&gt;</em>\Common7\IDE\ProjectTemplates\CSharp\Web\<em>&lt;Locale&gt;</em>\</span>.</p>
<p>I&rsquo;m sure I&rsquo;ll keep tweaking things about my empty MVC project template (I&rsquo;m already considering deleting the <span style="font-family: 'Lucida Console';">Models</span> directory since I tend to use a separate assembly for them) but I&rsquo;m happy with it as a first iteration. It&rsquo;s a pretty simple process to create one, so if you&rsquo;ve been annoyed at the stock MVC template, it&rsquo;s worth the minimal time investment.</p>
<p><span style="font-size: xx-small;"><em>This post targets Visual Studio 2008 and ASP.NET MVC 1.0 using C#. The content may not be relevant for other product, framework or language versions.</em></span></p>]]></content></entry><entry><title>Code Fossil: CacheManager</title><category term="ASP.NET"/><category term="Ramblings"/><id>http://www.kevinrohrbaugh.com/blog/2009/10/2/code-fossil-cachemanager.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/10/2/code-fossil-cachemanager.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-10-02T19:00:44Z</published><updated>2009-10-02T19:00:44Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><a href="http://www.flickr.com/photos/86624586@N00/11207971/"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="A fossilized frog - Photo by: kevinzim (Flickr)" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-CodeFossilCacheManager_20D-?fileId=4320372" border="0" alt="A fossilized frog - Photo by: kevinzim (Flickr)" width="244" height="210" align="right" /></a> Occasionally, I like to go back and review my code after it&rsquo;s had some time to age. This can be a great way to see how you&rsquo;ve personally evolved as a developer. Typically this process happens during maintenance through ongoing refactoring, and can be hard to notice. Sometimes, however, there are little applications that may not get worked on much and, since they do their job, they just chug along in production for year after year. These are what I think of as code fossils: code that got stuck in tree sap and became a preserved snapshot of your former self.</p>
<p>A code fossil of my own is the caching system I built using .NET 1.1 in the summer of 2004. What follows is a short synopsis and critique about the code.</p>
<h3>Requirements</h3>
<p>The application I was building was a rather simple content-aggregation web application. One of the business requirements was for it to &ldquo;be fast&rdquo; which typically translates to &ldquo;is cached&rdquo;. At a high level, here are some requirements:</p>
<ul>
<li>Content retrieved from other systems must not access those systems for every request served (i.e. content must be cached locally to minimize load on source systems).</li>
<li>Should source systems be unavailable at the time of cache expiration, cached content should be retained and used.</li>
</ul>
<p>From these basic requirements, I seem to have added my own:</p>
<ul>
<li>Cache configuration should be flexible, so that it&rsquo;s possible to disable caching globally or change where any given piece of content is cached using a configuration file.</li>
<li>Cache settings, such as expiry method and duration, should also be configurable without code changes.</li>
</ul>
<h3>Implementation</h3>
<p>From these requirements (including those that I made up myself) I built the <span style="font-family: 'Lucida Console';">ContentManager</span> class and it&rsquo;s partners in crime, the <span style="font-family: 'Lucida Console';">CacheManger</span> and <span style="font-family: 'Lucida Console';">IDataLoader</span>:</p>
<p><a href="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-CodeFossilCacheManager_20D-?fileId=4320373"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="class-diagram" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-CodeFossilCacheManager_20D-?fileId=4320374" border="0" alt="class-diagram" width="597" height="300" /></a>Essentially, these classes (along with a few others) worked together so that the application code would request a piece of content using the <span style="font-family: 'Lucida Console';">GetContent()</span> method on the <span style="font-family: 'Lucida Console';">ContentManager</span> singleton (<span style="font-family: 'Lucida Console';">ContentManager.Manager</span>). The <span style="font-family: 'Lucida Console';">ContentManager</span> then determined if said content was cached and invoked the <span style="font-family: 'Lucida Console';">LoadContent()</span> method on <span style="font-family: 'Lucida Console';">CacheManager</span>&rsquo;s singleton, which either retrieved the content from cache or triggered the <span style="font-family: 'Lucida Console';">ContentNotFound</span> event. The <span style="font-family: 'Lucida Console';">ContentNotFoundEvent</span> then, through a strange design decision, invoked the <span style="font-family: 'Lucida Console';">ContentManager</span> to load the content using an <span style="font-family: 'Lucida Console';">IDataLoader</span> that was resolved using some XML configuration in custom sections of the Web.config file for the application.</p>
<p>All of this resolution was done with three layers of configuration: content mappings, cache categories and content loaders. Content mappings linked pieces of content to a cache category, which specified where and how content was cached (for instance ASP.NET Application, Session or Cache objects). Content loaders mapped content to classes that loaded the content when it wasn&rsquo;t available in the cache. As outlined above, all of this was done using custom configuration sections in the Web.config, meaning that it involved several more classes to map all this information within the application.</p>
<h3>Critique</h3>
<p>This design makes me squirm, to the point that I was hesitant about posting it at all. First of all, when it&rsquo;s all said and done there are ten classes dedicated to all this mapping, configuration and dynamic caching. To cap it all off, the method signature for <span style="font-family: 'Lucida Console';">GetContent</span> (and related) looks like this:</p>
<pre class="brush: csharp;">public object GetContent(string contentKey)
{
    object content = null;

    // Redacted to protect the innocent

    return content;
}</pre>
<p>That&rsquo;s right, the entire system hinges on (case-sensitive) <a href="http://en.wikipedia.org/wiki/Magic_string_%28programming%29">magic strings</a> and returns <span style="font-family: 'Lucida Console';">object</span>.</p>
<p>In the end, here are some things that immediately pop to mind when I look at this code today:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it">YAGNI</a> &amp; <a href="http://en.wikipedia.org/wiki/Keep_it_simple_stupid">KISS</a>: The truth is, a lot of this caching code was just fun for me to play with. I was brand new to ASP.NET at the time, so I got to learn about custom configuration sections and all the various options you can set when putting items in <a href="http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx">System.Web.Caching.Cache</a>. In the end, though, these settings never got tweaked once the application development was done and there were better things I could have spent my time on. It&rsquo;s true that being able to disable caching was useful during the development cycle, but I wasted a lot of time building an overly flexible cache system that simply wasn&rsquo;t needed.</li>
<li>Avoid anti-patterns and use design patterns sensibly: Heavy reliance on the <a href="http://en.wikipedia.org/wiki/Magic_string_%28programming%29">magic string</a> anti-pattern for all the cache mapping resulted in a brittle system that tightly coupled URL patterns to the underlying content. Additionally, while <a href="http://en.wikipedia.org/wiki/Singleton_pattern">singletons</a> are useful in some situations, applying them here makes it difficult to unit test any code that uses these classes (which, in this case, is the rest of the application). Not surprisingly, this application has very few unit tests. </li>
<li>Use Output Caching: The saddest part of this entire endeavor is that all that&rsquo;s being cached here is the content to be displayed, in the domain objects used to display it. In other words, the content is still being rendered by ASP.NET on every request. Since performance concerns were the central business need and much of the content was largely static, output caching would have likely proved more beneficial, even with the drawbacks it had in ASP.NET 1.0.</li>
<li>Class naming: Naming a class is often challenging as it tends to set the tone for what its purpose is. When you name something with <a href="http://www.bright-green.com/blog/2003_02_25/naming_java_classes_without_a.html">the Manager suffix</a>, it&rsquo;s likely that you don&rsquo;t know what exactly the class is supposed to be doing, which means it&rsquo;s likely to end up doing more than it should. Case in point: The <span style="font-family: 'Lucida Console';">ContentManager</span> is what other parts of the application call to retrieve content, and it&rsquo;s also what is invoked (through an event) when a cache miss occurs. </li>
</ul>
<h3>What I&rsquo;d Change</h3>
<p>This isn&rsquo;t meant to be a full design review, so I won&rsquo;t outline a complete design for how I&rsquo;d implement this today, but instead offer a brief overview.</p>
<p>In place of <span style="font-family: 'Lucida Console';">ContentManager</span> and <span style="font-family: 'Lucida Console';">CacheManager</span>, I&rsquo;d employ service objects that exposed the actual domain objects for the specific pieces of content. The service objects wouldn&rsquo;t use static methods and would be passed into the page presenter objects using dependency injection. To add caching, I&rsquo;d either use AOP or sub-classes of the service objects that perform caching duties, most likely using keys generated from class and method names and not exposed to the user in any form. This would make it possible to control caching using the IoC container or AOP framework, rather than a host of custom XML and configuration classes. In most cases, the service objects would call out to repository objects that would retrieve the content from the appropriate data store (taking the place of <span style="font-family: 'Lucida Console';">IDataLoader</span>).&nbsp;</p>
<p>I wouldn&rsquo;t bother with supporting overly flexible cache settings as the need doesn&rsquo;t exist. I&rsquo;d also employ output caching much more heavily and only use the above caching strategy for those content areas with external dependencies, as the requirements dictate.</p>
<h3>Closing Thoughts</h3>
<p><a href="http://www.flickr.com/photos/astros/2147311501/"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="Stegosaurus - Photo by: texas_mustang (Flickr)" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-CodeFossilCacheManager_20D-?fileId=4320375" border="0" alt="Stegosaurus - Photo by: texas_mustang (Flickr)" width="244" height="164" align="right" /></a> To be honest, I&rsquo;ve never looked at any code I&rsquo;ve written months ago and felt anything better than mild contempt toward it. Perhaps I&rsquo;m just not that talented a developer, but I suspect that this is probably the case for most of us.</p>
<p>At the end of it all, the dirty little secret is the caching system is still chugging along in production, doing its (not so elegantly designed) job every day. While code fossils are fun as they highlight how you're development technique has evolved, it&rsquo;s also important to remember that they aren&rsquo;t necessarily past failures. After all, dinosaurs may not have proven to be the most resilient life-forms around, but they can inform us about today&rsquo;s world and did pretty well for 160 million years or so.</p>]]></content></entry><entry><title>Controller Scope &amp;amp; Testing</title><category term="ASP.NET MVC"/><category term="Testing"/><id>http://www.kevinrohrbaugh.com/blog/2009/9/25/controller-scope-amp-testing.html</id><link rel="alternate" type="text/html" href="http://www.kevinrohrbaugh.com/blog/2009/9/25/controller-scope-amp-testing.html"/><author><name>Kevin Rohrbaugh</name></author><published>2009-09-25T16:19:41Z</published><updated>2009-09-25T16:19:41Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>The transition from Web Forms to MVC can be challenging, and perhaps the trickiest aspect is controller scope. It’s rather easy for Web Forms developers, especially those who never adopted <a href="http://msdn.microsoft.com/en-us/magazine/cc188690.aspx">Model-View-Presenter</a> (or similar patterns), to persist the bad habit of sticking too much functionality in page code-behinds by building massive, monolithic controllers in MVC.</p>  <p><a href="http://www.flickr.com/photos/28481088@N00/292898253/"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="Complicated utility pole wiring; Photo by: tanakawho (Flickr)" border="0" alt="Complicated utility pole wiring; Photo by: tanakawho (Flickr)" align="right" src="http://www.kevinrohrbaugh.com/resource/WindowsLiveWriter-ControllerScopeTesting_AC79-?fileId=4256462" width="345" height="244" /></a>My <a href="http://www.kevinrohrbaugh.com/blog/2009/9/11/are-your-controllers-playing-music.html">earlier post</a> gave my thoughts on what a controller does metaphorically, but I came across a <a href="http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%E2%80%93-skinny-controllers/">more concrete post about the same topic</a> on Jag Reehal’s <a href="http://www.arrangeactassert.com/">Arrange Act Assert blog</a>. Skinny controllers are a key concept in MVC, and really shouldn’t be understated, so it’s a topic I’m likely to continue returning to. </p>  <p>Abstractly, it’s easy to talk about bloated controllers and how dangerous they are, but how do you tell when your controllers are getting fat? One way of detecting controller bloat is the difficulty encountered when unit testing them. As increased testability is a highly touted feature of ASP.NET MVC, many developers moving to it are also becoming interested in unit testing, some of which for the first time. If you find yourself staring at the Visual Studio code editor, contemplating how you should test your controller action methods, it’s highly likely that the controller is simply doing too much. Thankfully, Jag also wrote a <a href="http://www.arrangeactassert.com/how-to-unit-test-asp-net-mvc-controllers/">good post outlining how to unit test controllers</a> that’s worth your time. </p>  <p>Bloated controllers are likely to yield complicated, difficult to maintain code-bases, which can lead to the same problems encountered in poorly-designed Web Forms applications. Since avoiding such issues is often a catalyst for moving to MVC in the first place, it behooves developers to be diligent and avoid the practices that lead down the same painful path. Adopting a design pattern in name but not in principle won’t deliver the intended benefits and it is still all-too-possible to build a poorly-designed web application using ASP.NET MVC. In other words, the framework won’t rescue you on its own, real, sustained behavior change is necessary.</p>  <p>Put your controllers on a diet, and <a href="http://www.youtube.com/watch?v=91C7ax0UAAc">keep them skinny</a>!</p>]]></content></entry></feed>