<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.mozingo.net/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Taller Code</title>
	
	<link>http://darrell.mozingo.net</link>
	<description>Darrell Mozingo's blog on .NET and development in general</description>
	<pubDate>Sat, 28 Jan 2012 12:48:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.mozingo.net/TallerCode" /><feedburner:info uri="tallercode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Continuous Delivery</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/3YuLmh5orvg/</link>
		<comments>http://darrell.mozingo.net/2011/12/30/continuous-delivery/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 00:14:39 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Build Management]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1213</guid>
		<description><![CDATA[I recently finished reading Continuous Delivery. It&#8217;s an excellent book that manages to straddle that &#8220;keep it broad to help lots of people yet specific enough to actually give value&#8221; line pretty well. It covers testing strategies, process management, deployment strategies, and more.

At my former job we had a PowerShell script that would handle our [...]]]></description>
			<content:encoded><![CDATA[<p>I recently finished reading <a href="http://www.amazon.com/gp/product/0321601912">Continuous Delivery</a>. It&#8217;s an excellent book that manages to straddle that &#8220;keep it broad to help lots of people yet specific enough to actually give value&#8221; line pretty well. It covers testing strategies, process management, deployment strategies, and more.</p>

<p>At my former job we had a PowerShell script that would handle our deployment and related tasks. Each type of build - commit, nightly, push, etc. - all worked off its own artifacts that it created right then, duplicating any compilation, testing, or pre-compiling tasks. That eats up a lot of time. Here&#8217;s a list of posts where I covered how that script generally works:</p>

<ul>
<li><a href="http://darrell.mozingo.net/2010/09/24/production-deployment-with-your-build-script-part-1/">Part 1</a></li>
<li><a href="http://darrell.mozingo.net/2010/11/12/production-deployment-with-your-build-script-part-2/">Part 2</a></li>
<li><a href="http://darrell.mozingo.net/2010/11/24/production-deployment-with-your-build-script-part-3/">Part 3</a></li>
<li><a href="http://darrell.mozingo.net/2010/12/03/production-deployment-with-your-build-script-part-4/">Part 4</a></li>
</ul>

<p>The book talks about creating a single set of artifacts from the first commit build, and passing those same artifacts through the pipeline of UI tests, acceptance tests, manual testing, and finally deployment. I really like that idea, as it cuts down on unnecessary rework, and gives you more confidence that this one set of artifacts are truly ready to go live. Sure, the tasks could call the same function to compile the source or run unit tests, so it was effectively the same, but there could have been slight differences where the assemblies produced from the commit build were slightly different than those in the push build.</p>

<p>I also like how they mention getting automation in your project from day one if you&#8217;re lucky enough to work on a green-field app. I&#8217;ve worked on production deployment scripts for legacy apps and for ones that weren&#8217;t production yet, but still a year or so old. The newer an app is and the less baggage it has, the easier it is to get started, and getting started is the hardest part. Once you have a script that just compiles and copies files, you&#8217;re 90% of the way there. You can tweak things and add rollback functionality later, but the meat of what&#8217;s needed is there.</p>

<p>However you slice it, <strong>you have to automate your deployments</strong>. If you&#8217;re still copying files out by hand, you&#8217;re flat out doing it wrong. In the age of PowerShell, there&#8217;s really no excuse to not automate your line of business app deployment. The faster deliveries, more transparency, and increased confidence that automation gives you can only lead to one place: <a href="http://darrell.mozingo.net/2011/06/26/the-pit-of-success/">the pit of success</a>, and that&#8217;s a good place to be.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/3YuLmh5orvg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/12/30/continuous-delivery/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/12/30/continuous-delivery/</feedburner:origLink></item>
		<item>
		<title>Moving on</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/BeIBoI4RgUk/</link>
		<comments>http://darrell.mozingo.net/2011/11/14/moving-on/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 22:15:57 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Misc.]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1352</guid>
		<description><![CDATA[I&#8217;ve been at Synergy Data Systems for over 7 years now (I know, the site is horrible). I&#8217;ve worked with a lot of great people on some very interesting projects, and learned a boat load during that time. Unfortunately, they can&#8217;t offer the one thing my wife and I wanted: living abroad.

To that end, we&#8217;re [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been at <a href="http://synergydatasystems.com/">Synergy Data Systems</a> for over 7 years now (I know, the site is horrible). I&#8217;ve worked with a lot of great people on some very interesting projects, and learned a boat load during that time. Unfortunately, they can&#8217;t offer the one thing my wife and I wanted: living abroad.</p>

<p>To that end, we&#8217;re moving to London and I&#8217;ll be starting at <a href="http://about.7digital.net/">7digital</a> in early January. I&#8217;m super excited about both moves. 7digital seems like a great company working with a lot of principals and practices that are near and dear to me, and c&#8217;mon, it&#8217;s London. For two people that grew up in small town Ohio, this&#8217;ll be quite the adventure!</p>

<p>I&#8217;m looking forward to getting involved in the huge developer community over there, playing with new technologies, and working with fellow craftsmen!</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/BeIBoI4RgUk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/11/14/moving-on/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/11/14/moving-on/</feedburner:origLink></item>
		<item>
		<title>Painfully slow clone speeds with msysgit &amp; GitExtensions</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/N4nXpuZksuU/</link>
		<comments>http://darrell.mozingo.net/2011/09/29/painfully-slow-clone-speeds-with-msysgit-gitextensions/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 22:49:10 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Quickie]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1329</guid>
		<description><![CDATA[If you install GitExtensions, up through the current 2.24 version (which comes bundled with the latest msysgit version 1.7.6-preview20110708), and use OpenSSH for your authentication (as opposed to Plink), you&#8217;ll likely notice some painfully slow cloning speeds. Like 1MB/sec on a 100Mb network kinda slow.

Thankfully, it&#8217;s a pretty easy fix. Apparently msysgit still comes bundled [...]]]></description>
			<content:encoded><![CDATA[<p>If you install <a href="http://code.google.com/p/gitextensions/">GitExtensions</a>, up through the current 2.24 version (which comes bundled with the latest <a href="http://code.google.com/p/msysgit/">msysgit</a> version 1.7.6-preview20110708), and use OpenSSH for your authentication (as opposed to Plink), you&#8217;ll likely notice some painfully slow cloning speeds. Like 1MB/sec on a 100Mb network kinda slow.</p>

<p>Thankfully, it&#8217;s a pretty easy fix. Apparently msysgit still comes bundled with <a href="http://groups.google.com/group/msysgit/browse_thread/thread/c47054f2d14d0981">an ancient version of OpenSSH</a>:</p>

<pre>
$ ssh -V
OpenSSH_4.6p1, OpenSSL 0.9.8e 23 Feb 2007
</pre>

<p>Until they get it updated, it&#8217;s easy to do yourself. Simply install the latest version of <a href="http://cygwin.com/setup.exe">Cygwin</a>, and make sure to search for and install OpenSSH on the package screen. Then go into the <code>/bin</code> directory of where you installed Cygwin, and copy the following files into <code>C:\Program Files\Git\bin</code> (or <code>Program Files (x86)</code> if you&#8217;re on 64-bit):</p>

<ul>
<li>cygcrypto-0.9.8.dll</li>
<li>cyggcc_s-1.dll</li>
<li>cygssp-0.dll</li>
<li>cygwin1.dll</li>
<li>cygz.dll</li>
<li>ssh.exe</li>
<li>ssh-add.exe</li>
<li>ssh-agent.exe</li>
<li>ssh-keygen.exe</li>
<li>ssh-keyscan.exe</li>
</ul>

<p>Checking the OpenSSH version should yield something a bit higher now:</p>

<pre>
$ ssh -V
OpenSSH_5.8p1, OpenSSL 0.9.8r 8 Feb 2011
</pre>

<p>Your clone speeds should be faster too. This upgrade bumped ours from literally around 1MB/sec to a bit over 10MB/sec. Nice.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/N4nXpuZksuU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/09/29/painfully-slow-clone-speeds-with-msysgit-gitextensions/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/09/29/painfully-slow-clone-speeds-with-msysgit-gitextensions/</feedburner:origLink></item>
		<item>
		<title>Getting started with TDD</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/S53UjdHDsUg/</link>
		<comments>http://darrell.mozingo.net/2011/09/15/getting-started-with-tdd/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 02:38:33 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1128</guid>
		<description><![CDATA[When I first read about TDD and saw all the super simple examples that litter the inter-tubes, like the calculator that does nothing but add and subtract, I thought the whole thing was pretty stupid and it&#8217;s approach to development was too naive. Thankfully I didn&#8217;t write the practice off - I started trying it, [...]]]></description>
			<content:encoded><![CDATA[<p>When I first read about TDD and saw all the super simple examples that litter the inter-tubes, like the calculator that does nothing but add and subtract, I thought the whole thing was pretty stupid and it&#8217;s approach to development was too naive. Thankfully I didn&#8217;t write the practice off - I started trying it, plugging away here and there. One thing I eventually figured out was that TDD is a lot like math. You start out easy (addition/subtraction), and continue building on those fundamentals as you get used to it.</p>

<p>So my suggestion to those starting down the TDD path is: don&#8217;t brush it off. Start simple. Do the simple calculator, the stack, or the bowling game. Don&#8217;t start thinking about how to mix in databases, UI&#8217;s, web servers, and all that other crud with the tests. Yes, these examples are easy, and yes they ignore a lot of stuff you need to use in your daily job, but that&#8217;s sort of the point. They&#8217;ll seem weird and contrived at first, but that&#8217;s OK. It serves a very real purpose. TDD has been around for a good while now, it&#8217;s not some fad that&#8217;s going away. People use it and get real value out of it.</p>

<p>The basic practice examples getting you used to the TDD flow - red, green, refactor. That&#8217;s the whole point of things like <a href="http://darrell.mozingo.net/code-katas/">kata&#8217;s</a>. Convert that flow into muscle memory. Get it ingrained in your brain, so when you start learning the more advanced practices (DIP, IoC containers, mocking, etc), you&#8217;ll just be building on that same basic flow. Write a failing test, make it pass, clean up. You don&#8217;t want to abandon that once you start learning more and going faster.</p>

<p>It seems everyone gets the red-green-refactor part down when they&#8217;re doing the simple examples, but forget it once they start working on production code. Sure, you don&#8217;t always know what your code is going to do or look like, but that&#8217;s why we have the tests. If you can&#8217;t even begin to imagine how your tests will work, write some throw away spike code. Get it working functionally, then delete it all and start again using TDD. You&#8217;ll be surprised how it changes.</p>

<p>Good luck with your journey. If you&#8217;re in the Canton area, don&#8217;t forget to check out the monthly <a href="http://www.meetup.com/Canton-Software/">Canton Software Craftsmanship</a> meetup. There&#8217;s experienced people there that are eager to help you out.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/S53UjdHDsUg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/09/15/getting-started-with-tdd/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/09/15/getting-started-with-tdd/</feedburner:origLink></item>
		<item>
		<title>Commenting out old code kills puppies</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/nHAuFCFAoU4/</link>
		<comments>http://darrell.mozingo.net/2011/07/28/commenting-out-old-code-kills-puppies/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 04:42:48 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1299</guid>
		<description><![CDATA[There, I said it. Actually, I&#8217;m kind of worried that title won&#8217;t adequately state the intensity of this situation.

This is one of the fundamental reasons we have source control people, so we can go back through a file&#8217;s history and see the different revisions. Please, for the love of all that is holy, don&#8217;t comment [...]]]></description>
			<content:encoded><![CDATA[<p>There, I said it. Actually, I&#8217;m kind of worried that title won&#8217;t adequately state the intensity of this situation.</p>

<p>This is one of the fundamental reasons we have source control people, so we can go back through a file&#8217;s history and see the different revisions. Please, for the love of all that is holy, don&#8217;t comment out old code. <strong>Just delete it!</strong> Feel free to slap your own knuckles with a ruler if you start to think about commenting it. Don&#8217;t try to recreate a source control system through commented out code. Everyone knows exactly what I&#8217;m talking about:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">// John Doe - 7/5/2011 - Changed to allow a higher limit.</span>
<span style="color: #008080; font-style: italic;">// dozens of lines of old code....</span>
&nbsp;
<span style="color: #008080; font-style: italic;">// John Doe - 7/18/2011 - Changed algorithm slightly.</span>
<span style="color: #008080; font-style: italic;">// dozens of lines of old code....</span>
&nbsp;
<span style="color: #008080; font-style: italic;">// random dozen lines of old code with no comment at all</span>
&nbsp;
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ActualCode<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #000000;">&#125;</span></pre></td></tr></table></div>




<p>Those extra comment chunks are just crap to sift through to get to the real code, extra stuff you&#8217;ll have to parse to see if it&#8217;s relevant to the current situation, and creating more false-positives for ReSharper (and I&#8217;m guessing other refactoring tools) to pick up when you rename a variable/method that&#8217;s used inside those commented chunks. That chunk of old code at the bottom without even a hint as to why it&#8217;s commented out? That&#8217;s the worst of the worst - someone&#8217;s going to sit there and stare at it for a good while before they figure out why it was commented out, and we know when the author actually committed this file with that commented out the commit comment was blank too. Awesome.</p>

<p>So anyway, just remember what actually happens the next time you&#8217;re about to comment out old code and <strong>don&#8217;t do it</strong>, you&#8217;ll be doing future programers (and more than likely yourself) a huge service&#8230;</p>

<img src="http://darrell.mozingo.net/wp-content/uploads/2011/07/dead_puppies.jpg" alt="Commenting code kills puppies" title="Commenting code kills puppies" width="500" /><img src="http://feeds.feedburner.com/~r/TallerCode/~4/nHAuFCFAoU4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/07/28/commenting-out-old-code-kills-puppies/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/07/28/commenting-out-old-code-kills-puppies/</feedburner:origLink></item>
		<item>
		<title>Consistent modal dialogs, the easy way</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/GhGKaLTYtY0/</link>
		<comments>http://darrell.mozingo.net/2011/07/20/consistent-modal-dialogs-the-easy-way/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 22:28:01 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1224</guid>
		<description><![CDATA[So we all know the default alert dialog box visually sucks. Any of the hundreds of jQuery modal plugins work wonderfully for replacing it with something a bit snazzier (although putting the information on the page for a user is even better, but that&#8217;s for another post). The biggest problem with most of those dialogs [...]]]></description>
			<content:encoded><![CDATA[<p>So we all know the default alert dialog box visually sucks. Any of the hundreds of jQuery modal plugins work wonderfully for replacing it with something a bit snazzier (although putting the information on the page for a user is even better, but that&#8217;s for another post). The biggest problem with most of those dialogs are either the setup cost, or the memory cost:</p>

<ul>
<li><b>Setup cost</b>: having to set heights, widths, button names, text &#038; title fields, yada, yada, yada. A lot of that can be skinned through CSS, and a lot of plugins reduce that noise to virtually nil, but many leave a lot on your pages. It&#8217;s ugly to look at in your code, and ugly to configure. Not to mention all those config settings spreads through your code base like the freakin&#8217; ground ivy is spreading through my lawn as I type this. Want to change the widths for a new redesign, or localize the button names? Good luck!</li>
<li><b>Memory cost</b>: relates to the <a href="http://darrell.mozingo.net/2011/06/26/the-pit-of-success/">Pit of Success</a>. Do you really want the burden of always remembering to use that modal dialog instead of alert? What about the new guy, is he going to know or remember? Sure, forgetting isn&#8217;t <i>that</i> big of a deal, but given enough slip ups and your nice consistent UI goes to hell. Tests checking for calls to alert are also possible via straight searching through files or through UI tests some how, but I can see a future of false positives ahead of that idea.</li>
</ul>

<p>How about a better way? With some very slight Javascript-foo, you can override the default alert and confirm dialogs so not only is there nothing to copy &#038; paste between pages, but you don&#8217;t even have to remember to use your nifty modal boxes - it&#8217;ll just happen. We&#8217;ll use the <a href="http://jqueryui.com/demos/dialog/">jQuery UI Dialog</a> plugin inside a stock ASP.NET MVC app, though this is easily transferable to any other platform or with any other modal plugin.</p>

<p>First we&#8217;ll override the default <code>alert</code> method on the <code>window</code> object, calling the dialog function from jQuery UI and setting some default parameters:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">window.<span style="color: #0000FF;">alert</span> <span style="color: #008000;">=</span> function <span style="color: #000000;">&#40;</span>message<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	$<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;#dialog&quot;</span><span style="color: #000000;">&#41;</span>
	.<span style="color: #0000FF;">html</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>
	.<span style="color: #0000FF;">html</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">'&lt;span class=&quot;ui-icon ui-icon-alert custom-ui-icon&quot;&gt;&lt;/span&gt;'</span> <span style="color: #008000;">+</span> message<span style="color: #000000;">&#41;</span>
	.<span style="color: #0000FF;">dialog</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#123;</span>
		autoOpen<span style="color: #008000;">:</span> <span style="color: #0600FF;">true</span>,
		resizable<span style="color: #008000;">:</span> <span style="color: #0600FF;">false</span>,
		height<span style="color: #008000;">:</span> <span style="color: #FF0000;">200</span>,
		width<span style="color: #008000;">:</span> <span style="color: #FF0000;">350</span>,
		title<span style="color: #008000;">:</span> <span style="color: #666666;">&quot;Alert!&quot;</span>,
		modal<span style="color: #008000;">:</span> <span style="color: #0600FF;">true</span>,
		buttons<span style="color: #008000;">:</span> <span style="color: #000000;">&#123;</span>
			<span style="color: #666666;">&quot;OK&quot;</span><span style="color: #008000;">:</span> function <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
				$<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">dialog</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;close&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
				return<span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
alert<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Error!!!&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>




<p>The HTML is cleared out and a default alert icon (from jQueryUI) is added via the class attribute <code>ui-icon-alert</code>. This allows us to create a standard <code>&lt;div id="dialog"&gt;&lt;/div&gt;</code> in our master page with nothing inside it, and reuse it for alert/confirm/prompt boxes. Then a standard alert call, like the one at the bottom, gives us:</p>

<img src="http://darrell.mozingo.net/wp-content/uploads/2011/07/alert_modal.png" alt="Alert modal dialog" title="Alert modal dialog" /> vs 
<img src="http://darrell.mozingo.net/wp-content/uploads/2011/07/alert_default.png" alt="Default alert" title="Default alert" />

<p>Similarly, we can override the default confirmation box. Here&#8217;s a version that&#8217;ll take the title, a message to show, and a callback function to execute if the user clicks &#8220;OK&#8221;:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">window.<span style="color: #0000FF;">confirm</span> <span style="color: #008000;">=</span> function<span style="color: #000000;">&#40;</span>title, confirmMessage, successCallback<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	$<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;#dialog&quot;</span><span style="color: #000000;">&#41;</span>
		.<span style="color: #0000FF;">html</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>
		.<span style="color: #0000FF;">html</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">'&lt;span class=&quot;ui-icon ui-icon-help custom-ui-icon&quot;&gt;&lt;/span&gt;'</span> <span style="color: #008000;">+</span> confirmMessage<span style="color: #000000;">&#41;</span>
		.<span style="color: #0000FF;">dialog</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#123;</span>
				autoOpen<span style="color: #008000;">:</span> <span style="color: #0600FF;">true</span>,
				resizable<span style="color: #008000;">:</span> <span style="color: #0600FF;">false</span>,
				height<span style="color: #008000;">:</span> <span style="color: #FF0000;">200</span>,
				width<span style="color: #008000;">:</span> <span style="color: #FF0000;">350</span>,
				title<span style="color: #008000;">:</span> title,
				modal<span style="color: #008000;">:</span> <span style="color: #0600FF;">true</span>,
				buttons<span style="color: #008000;">:</span> <span style="color: #000000;">&#123;</span>
					<span style="color: #666666;">&quot;Yes&quot;</span><span style="color: #008000;">:</span> function<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
						$<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">dialog</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;close&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
						successCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
						return<span style="color: #008000;">;</span>
					<span style="color: #000000;">&#125;</span>,
					<span style="color: #666666;">&quot;No&quot;</span><span style="color: #008000;">:</span> function<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
						$<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">dialog</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;close&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
						return<span style="color: #008000;">;</span>
					<span style="color: #000000;">&#125;</span>
				<span style="color: #000000;">&#125;</span>
			<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
confirm<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Are you sure?&quot;</span>, <span style="color: #666666;">&quot;Are you sure you want to create a confirm?&quot;</span>, function<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> alert<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Sweet, all done!&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>




<p>Again, compare the results (the first question mark is an icon from jQuery UI, which can also be changed with the class written out in the confirm method above):</p>

<img src="http://darrell.mozingo.net/wp-content/uploads/2011/07/confirm_modal.png" alt="Modal Confirm" title="Modal Confirm" /> vs 
<img src="http://darrell.mozingo.net/wp-content/uploads/2011/07/confirm_default.png" alt="Default Confirm" title="Default Confirm" />

<p>Pretty neat, if you ask me. This whole thing is very <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>, as everything you need is referenced in your master page (the dialog div, the javascript &#038; css files, etc) and your individual pages don&#8217;t need to include anything - just call away. You also don&#8217;t have to remember to call special methods (or at least terribly special ones in <code>confirm</code>&#8217;s case). It just works.</p>

<p>It&#8217;s not too hard to imagine extending this system to override the default <code>prompt</code> box either. Just pass in a callback that&#8217;ll set whatever string you need, similar to how <code>confirm</code> works above. Closures work wonders.</p>

<p>You can grab the code used in this post <a href="https://github.com/DarrellMozingo/Blog/tree/master/ConsistentModalDialogs">right here</a>.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/GhGKaLTYtY0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/07/20/consistent-modal-dialogs-the-easy-way/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/07/20/consistent-modal-dialogs-the-easy-way/</feedburner:origLink></item>
		<item>
		<title>The Pit of Success</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/ZrGIoU8eW04/</link>
		<comments>http://darrell.mozingo.net/2011/06/26/the-pit-of-success/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 03:37:11 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Design Principles]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1208</guid>
		<description><![CDATA[

I&#8217;m a huge believer in the Pit of Success. Quite a few have written about it before, though not always in development terms. Put simply, there&#8217;s two pits you can create in your application through conventions, infrastructure, culture, tools, etc: success and failure. I obviously choose the former.

The Pit of Success is when you and [...]]]></description>
			<content:encoded><![CDATA[<img src="http://darrell.mozingo.net/wp-content/uploads/2011/06/pit-of-success.jpg" alt="Pit of Success" title="Pit of Success" style="float: right; padding-left: 5px" />

<p>I&#8217;m a <strong>huge</strong> believer in the Pit of Success. Quite a few have written <a href="http://blogs.msdn.com/b/brada/archive/2005/10/07/478375.aspx">about</a> <a href="http://www.codinghorror.com/blog/2007/08/falling-into-the-pit-of-success.html">it</a> <a href="http://blogs.msdn.com/b/brada/archive/2003/10/02/50420.aspx">before</a>, though not always in development terms. Put simply, there&#8217;s two pits you can create in your application through conventions, infrastructure, culture, tools, etc: success and failure. I obviously choose the former.</p>

<p>The Pit of Success is when you and the other developers on your team have to think less about the mundane stuff and when there&#8217;s only one easy development path to follow. Less thinking about crap = more thinking about business problems = faster software with less bugs. In general, if I see something that&#8217;s going to be in a lot of classes/pages and it has a decent bit of setup and baggage for it, I instantly picture another developer forgetting to bring all that along when they start new features or refactor. If things break (visually or programatically) when that happens, there&#8217;s a problem. Same goes for huge chunks of documentation explaining how to use a certain feature elsewhere in the system - time to make it easier to use! Here&#8217;s a few examples of how we&#8217;ve dug out a Pit of Success on our current project:</p>

<ul>
<li>Need to create a new schedule task? <a href="http://darrell.mozingo.net/2009/09/15/injecting-all-instances-of-a-given-type/">Drop in a class and implement a simple interface.</a> That same principal goes for a slew of other areas - missing information checks for users, HTTP handlers, sample data for geographic areas, etc. You don&#8217;t have to go hunting down a master class to add these new things to, just create the class and you&#8217;re golden.</li>
<li>Security in our system isn&#8217;t that complex yet, so we&#8217;re able to consolidate everything in a nice tidy <code>ActionFilter</code>. It&#8217;s applied to our custom controller, and we have a unit test that makes sure all Controllers in the system inherit from that custom one. So by following the rules (on your own or with the help of a broken test), you get security handled for you auto-magically.</li>
<li>We continuously deploy <a href="http://darrell.mozingo.net/2010/09/24/production-deployment-with-your-build-script-part-1/">with our build server</a>, so it takes care of not only making sure all our unit/integration tests pass, but that all the needed debug settings are flipped, sites are pre-compiled, everything still works once it&#8217;s live, etc. That saves us from remembering to do all that every time we push live, which is almost constantly these days.</li>
<li>We completely agree with Chad Myers, Jeremy Miller, et al: if we&#8217;re working with a static language, make the best of it. Everything in our system is strongly typed, from text box ids in HTML/Javascript/UI tests to URLs and help points. You shouldn&#8217;t have to remember to go hunting and pecking through the whole system when you want to rename something, just rename it with ReSharper and move on. Same with finding where something is being referenced. The harder it is to rename things, the less they get renamed, and the crustier the system gets.</li>
<li>We started creating one off modal dialogs to present information to the user. They looked great, but needed a lot of baggage and duplication to do it, so we overrode the default <code>alert</code> and <code>confirm</code> dialogs with our modal ones. Now there&#8217;s not only nothing to add to your page to get this, but in most cases you don&#8217;t even have to remember we&#8217;re overriding it! There&#8217;s a forthcoming post that&#8217;ll cover what we did in more detail.</li>
<li>We have a unit test that&#8217;ll scan through all of our test files (which end with *Fixture), and make sure there&#8217;s a file name that matches (sans the Fixture part) in the corresponding directory structure in the main assembly. We constantly move files around when refactoring, and forgetting to move or rename their test files is a pain, so this test gently reminds us. Note we don&#8217;t always follow a one-class-per-fixture setup, but even when we don&#8217;t, we stick them in a matching fixture class for easy grouping and ReSharper discoverability.</li>
</ul>

<p>It&#8217;s worth noting we didn&#8217;t set out from day one to build all this stuff. Its all grown over time as the project and our stakeholder&#8217;s needs have changed. We always strive to keep KISS in mind (<a href="http://darrell.mozingo.net/2008/06/18/kiss-is-hard/">even if it is hard</a>) and not build anything until it&#8217;s absolutely needed. Don&#8217;t try to create infrastructure to handle everything for you when a project&#8217;s in its infancy. Harvest it out later.</p>

<p>There&#8217;s also exceptions to all of these rules. Is automatic security always the right thing to do? No - if you need highly configurable security, put it out in the open and remember to set it on each request. Don&#8217;t force things into the infrastructure if they&#8217;re fighting you and have lots of exception cases. Perhaps there&#8217;s another route of attack that&#8217;ll solve the problem and still keep you circling around the Pit of Success.</p>

<p>You&#8217;ll create your own Pit of Success on your project just by falling into the bigger Pit of Success that is the SOLID principals. The majority of the examples up there were arrived at by just adhering to the Open/Closed Principal or the Single Responsibility Principal. They create a sort of recursive pit, I suppose.</p>

<p>What have you done on your projects to help create a Pit of Success?</p>


<img src="http://feeds.feedburner.com/~r/TallerCode/~4/ZrGIoU8eW04" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/06/26/the-pit-of-success/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/06/26/the-pit-of-success/</feedburner:origLink></item>
		<item>
		<title>Canton Software Craftsmanship</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/HYbBh8T9H0s/</link>
		<comments>http://darrell.mozingo.net/2011/05/27/canton-software-craftsmanship-3/#comments</comments>
		<pubDate>Fri, 27 May 2011 22:06:33 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1196</guid>
		<description><![CDATA[Just a quick reminder about the next Canton Software Craftsmanship meeting on June 6th. It&#8217;s the usual 6pm at Stark State College with free pizza and drinks, and sponsored by Synergy Data Systems this month (who&#8217;s coincidentally looking for another junior C# developer, if you&#8217;re interested). Asher McCune will be giving a talk on the [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick reminder about the next <a href="mycraftsmanship.org">Canton Software Craftsmanship</a> meeting on <b>June 6th</b>. It&#8217;s the usual <b>6pm</b> at Stark State College with free pizza and drinks, and sponsored by <a href="http://synergydatasystems.com/">Synergy Data Systems</a> this month (who&#8217;s coincidentally looking for another <a href="http://starkjobs.com/JobSeeker/Junior_Software_Developer__Programmer_WJ544824.aspx">junior C# developer</a>, if you&#8217;re interested). Asher McCune will be giving a talk on the <a href="http://en.wikipedia.org/wiki/Open/closed_principle">Open/Closed Principle</a> (the O in SOLID) and we&#8217;ll be doing more katas together, trying to push the pairing aspect and getting everyone to work with different partners.</p>

<p>Hope everyone can make it! Please don&#8217;t forget to <a href="http://software.eventbrite.com/">register right here</a> so we have a head count for pizza.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/HYbBh8T9H0s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/05/27/canton-software-craftsmanship-3/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/05/27/canton-software-craftsmanship-3/</feedburner:origLink></item>
		<item>
		<title>Code Katas</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/LTWvRXWaNls/</link>
		<comments>http://darrell.mozingo.net/2011/05/24/code-katas/#comments</comments>
		<pubDate>Tue, 24 May 2011 21:05:40 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Misc.]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1160</guid>
		<description><![CDATA[I added a page listing a bunch of code katas, mostly for my own reference, but I guess you guys can mooch off of it too.
Let me know if I&#8217;m missing any. I&#8217;ll expand the page as I stumble across more.

]]></description>
			<content:encoded><![CDATA[<p>I added a <a href="http://darrell.mozingo.net/code-katas/">page listing a bunch of code katas</a>, mostly for my own reference, but I guess you guys can mooch off of it too.</p>
<p>Let me know if I&#8217;m missing any. I&#8217;ll expand the page as I stumble across more.</p>

<img src="http://feeds.feedburner.com/~r/TallerCode/~4/LTWvRXWaNls" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/05/24/code-katas/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/05/24/code-katas/</feedburner:origLink></item>
		<item>
		<title>StirTrek: Thor Edition</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/01TzdgmvjQg/</link>
		<comments>http://darrell.mozingo.net/2011/05/09/stirtrek-thor-edition/#comments</comments>
		<pubDate>Tue, 10 May 2011 02:42:48 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1163</guid>
		<description><![CDATA[
I went with a few co-workers to Stir Trek this past Friday. They&#8217;ve put an event on for the past two years, but this was the first one I&#8217;ve been to. It was an excellent event. Good talks, very well planned out, and a pretty decent movie to boot! Here&#8217;s the talks I went to:

Are [...]]]></description>
			<content:encoded><![CDATA[<img src="http://darrell.mozingo.net/wp-content/uploads/2011/05/thor.png" alt="thor" title="thor" style="float: right;" />
<p>I went with a few co-workers to <a href="http://stirtrek.com">Stir Trek</a> this past Friday. They&#8217;ve put an event on for the past two years, but this was the first one I&#8217;ve been to. It was an excellent event. Good talks, very well planned out, and a pretty decent movie to boot! Here&#8217;s the talks I went to:</p>
<ul>
<li><b>Are You Satisfied With Your Tests?</b> (<a href="http://onestepback.org/">Jim Weirich</a>) - Jim gave a good overview of testing (do it, make them fast, etc.) and tips (clear naming, refactoring, when to combine/split tests, etc.). Overall pretty good. My co-workers gave a laugh as I harp on many of these points all the time already.</li>
<li><b>Node.js - Show and Tell</b> (<a href="http://twitter.com/rubybuddha">Leon Gersing</a>) - A neat explanation of this async javascript framework. Leon gave a demo of a simple client/server chat setup, and a run down of a slightly more advanced website. I hadn&#8217;t seen any Node.js stuff other than very broad overview articles, so it was cool to get the explanation of when/where to use it, and look at working examples. Unfortunately he ran out of time before getting to the testing examples, but I guess that give me a place to start in my personal learning.</li>
<li><b>Testable Object-Oriented JavaScript</b> (<a href="http://jonkruger.com/blog/">Jon Kruger</a>) - One of the better talks I attended, as it tilted more towards the intermediate/advanced level than others. Jon walked through a live demo of building out a simple Twitter client by test-driving the javascript with <a href="http://pivotal.github.com/jasmine/">Jasmine</a> to run the tests, and his custom <a href="https://github.com/JonKruger/JSView/">JS View</a> framework to fake out the HTML. Pretty darn neat, and I&#8217;m looking forward to digging into it a bit more for our new features, as they&#8217;ll be far more client-side dependent than previous ones, and we haven&#8217;t gotten to the UI part just yet.</li>
<li><b>Getting Started with User Research: DIY Quick Course</b> (<a href="http://www.askauser.com/">Carol Smith</a>) - Carol went over the basics of user research via interviews, observance, and card sorting, which helps you structure you application&#8217;s layout to match how users would expect it to be. Very helpful for a high-level overview talk, and gave me a few tips to pursue with getting information on our application.</li>
<li><b>Testing Web Applications with Selenium</b> (<a href="http://www.frazzleddad.com">Jim Holmes</a>) - I was definitely looking forward to this talk the most, and it didn&#8217;t disappoint. We use Watin at work and have only dabbled once in Selenium, so seeing how he structures his tests was helpful. Unfortunately he spent 80% of the time going over a basic UI test and overview of Selenium. By time he got to the lessons he&#8217;s learned from running 14,000 some-odd UI tests, he ran out of time. Booo. It was actually quite comical&#8230; &#8220;OK, now the most important things you need to know&#8230; I&#8217;m out of time, aren&#8217;t I?&#8221;. A few of the database/browser handling tips will come in handy for our UI test suite though, and I&#8217;m looking forward to giving them a shot.</li>
</ul>
<p>I really wanted to hit up the GitHub talk, executable requirements, and a mobile talk or two, but I guess there&#8217;s always next year. Overall it was an excellent conference, and the peeps that ran it did a great job. Thor itself turned out to be pretty decent flick, too.</p>
<p>They already scheduled next year&#8217;s version in May: StirTrek Avenger&#8217;s Edition. Looking forward to it!</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/01TzdgmvjQg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/05/09/stirtrek-thor-edition/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/05/09/stirtrek-thor-edition/</feedburner:origLink></item>
		<item>
		<title>Know your tools</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/4bHYG6xYg88/</link>
		<comments>http://darrell.mozingo.net/2011/04/11/know-your-tools/#comments</comments>
		<pubDate>Mon, 11 Apr 2011 05:22:11 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Musings]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1123</guid>
		<description><![CDATA[

How many carpenters do you think don&#8217;t know about kerf widths? How many plumbers don&#8217;t know the difference between MAPP and propane for soldering? Probably not many.

Masters of their craft know their tools inside and out. They don&#8217;t just skirt by barely knowing how to use them, and end up taking longer to complete a [...]]]></description>
			<content:encoded><![CDATA[<img src="http://darrell.mozingo.net/wp-content/uploads/2011/03/hobbywoodworkingbig2.jpg" alt="Tools" title="Tools" style="float: right;" width="450px" height="338px" />

<p>How many carpenters do you think don&#8217;t know about kerf widths? How many plumbers don&#8217;t know the difference between MAPP and propane for soldering? Probably not many.</p>

<p><b>Masters of their craft know their tools inside and out.</b> They don&#8217;t just skirt by barely knowing how to use them, and end up taking longer to complete a job because of that. We have the same situation in our craft. We use tools day in and day out - our IDE&#8217;s, debugging tools (for our main languages and web based ones), OS, browsers, websites, etc. They&#8217;re all tools of our trade. Learning how to really use them is just another stepping stone on the path to being a craftsman.</p>

<p>The best way to really make use of your tools and increase your programming speed is to <b>ditch the mouse</b>. Use the keyboard as much as possible, which can be almost everything. Really get good with the keyboard and you&#8217;ll be amazed at how much more efficiently you can pump out code and navigate around.</p>

<p>I use Windows and Visual Studio, so I&#8217;ll use that as an example. Visual Studio itself has a metric ton of built-in keyboard shortcuts, but add ReSharper to the mix, and you&#8217;re golden. <a href="http://www.jetbrains.com/resharper/docs/ReSharper50DefaultKeymap_VS_scheme.pdf">Check out the keyboard shortcut cheat sheet</a>, it&#8217;s ridiculous, and overwhelming. Pick one or two shortcuts you think you&#8217;ll use, then use those exclusively for a week. Make sure to purposely use them as much as possible until they become muscle memory. It won&#8217;t take long.</p>

<p>Look at Tools -> Settings -> Keyboard. There&#8217;s lots of stuff you can key bind on your own that doesn&#8217;t come setup by default. Create a key combination to run your unit tests rather than reaching for the mouse. If a default key combo feels unnatural for you, rebind it. Find something that works for you, and don&#8217;t be afraid to experiment.</p>

<p><b>Start learning keyboard shortcuts in other programs you use on a regular basis.</b> There&#8217;s cheat sheets for <a href="http://r.evhead.com/hodgepodge/gmail-shortcuts.html">GMail</a> and <a href="http://thomaskorte.com/archive/printable-cheat-sheet-for-google-reader/">Google Reader</a>. For your mouse-free text editing needs (and IDE needs if you&#8217;re super experimentative and working with .NET) there&#8217;s the grand-daddies themselves: <a href="http://www.vim.org/">VIM</a> and <a href="http://www.gnu.org/software/emacs/">Emacs</a>. There&#8217;s even plugins for Firefox (<a href="http://vimperator.org/vimperator">Vimperator</a>) and Chrome (<a href="http://vimium.github.com/">Vimium</a>) to make each browser navigable in a VIM-esque way, and other plugins for each browser to simply add more keyboard navigation tricks. Heck, there&#8217;s even a few VIM plugins for Visual Studio itself if you want to go all the way, including <a href="http://www.viemu.com/">ViEmu</a> (paid) and <a href="https://github.com/jaredpar/VsVim">VsVim</a> (free).</p>

<p>It&#8217;s also super helpful to get a keystroke launcher on your box, such as <a href="http://executor.dk/">Executor</a> (my personal favorite) or <a href="http://www.launchy.net/">Launchy</a>. These guys basically give you the standard Windows Run dialog on steroids - letting you make custom launch commands and scripts. Definitely play around with one of these and work it into your normal workflow. I find myself leaning on it all the time.</p>

<p>So start practicing with a keyboard-only setup today. Disable your mouse driver and force yourself. It&#8217;ll kill your productivity in the short term for sure, but it&#8217;ll pay dividends every day for the rest of your career once you get used to it. You&#8217;ll thank me in a few weeks. Seriously, I&#8217;m marking my calendar.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/4bHYG6xYg88" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/04/11/know-your-tools/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/04/11/know-your-tools/</feedburner:origLink></item>
		<item>
		<title>Canton Software Craftsmanship</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/-04KQ0WAJEw/</link>
		<comments>http://darrell.mozingo.net/2011/03/31/canton-software-craftsmanship-2/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 20:59:37 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1137</guid>
		<description><![CDATA[The next Canton Software Craftsmanship meeting is this Monday. We&#8217;ll be going over TDD basics by having everyone follow us along on simple exercises.

Register here if you&#8217;e interested.

Hope to see you there!]]></description>
			<content:encoded><![CDATA[<p>The next <a href="http://mycraftsmanship.org/">Canton Software Craftsmanship</a> meeting is this Monday. We&#8217;ll be going over TDD basics by having everyone follow us along on simple exercises.</p>

<p><a href="http://software.eventbrite.com/">Register here</a> if you&#8217;e interested.</p>

<p>Hope to see you there!</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/-04KQ0WAJEw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/03/31/canton-software-craftsmanship-2/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/03/31/canton-software-craftsmanship-2/</feedburner:origLink></item>
		<item>
		<title>First Canton Software Craftsmanship get together</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/Jn-wOfOqarc/</link>
		<comments>http://darrell.mozingo.net/2011/03/08/first-canton-software-craftsmanship-get-together/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 22:05:34 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1120</guid>
		<description><![CDATA[Thanks to everyone that attended the first Canton Software Craftsmanship meeting this past Monday. It was a great turn-out (around 33 people?) and everyone seemed genuinely excited to see where this goes, myself included. Good food and good discussions all around. Sign up for the next meeting on April 4th if you haven&#8217;t already, and [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to everyone that attended the first <a href="http://mycraftsmanship.org/">Canton Software Craftsmanship</a> meeting this past Monday. It was a great turn-out (around 33 people?) and everyone seemed genuinely excited to see where this goes, myself included. Good food and good discussions all around. Sign up for the next meeting on April 4th if you haven&#8217;t already, and be sure to spread the word to anyone that might be interested. Remember, we&#8217;re about the practices, not the language, so everyone&#8217;s welcome.</p>

<p>I&#8217;d also like to thank <a href="http://sonerdy.com/">Brandon Joyce</a> and <a href="http://www.linkedin.com/in/johnhoover">John Hoover</a> for doing a great job with the logistics needed to get this group off the ground. Great job guys!</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/Jn-wOfOqarc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/03/08/first-canton-software-craftsmanship-get-together/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/03/08/first-canton-software-craftsmanship-get-together/</feedburner:origLink></item>
		<item>
		<title>Taskie runner is now bundled</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/jMO1U2xNg-4/</link>
		<comments>http://darrell.mozingo.net/2011/03/04/taskie-runner-is-now-bundled/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 23:34:23 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[Taskie]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1092</guid>
		<description><![CDATA[The latest version of Taskie (which is available on NuGet) now comes bundled with a console runner. Simply implement ITaskieServiceLocator with your IoC container of choice, and put your compiled assembly with that implementation in the same directory as Taskie.exe. Taskie will pick up on the implementation and use it like normal.

This should reduce the [...]]]></description>
			<content:encoded><![CDATA[<p>The latest version of <a href="https://github.com/DarrellMozingo/Taskie">Taskie</a> (which is available on NuGet) now comes bundled with a console runner. Simply implement <code>ITaskieServiceLocator</code> with your IoC container of choice, and put your compiled assembly with that implementation in the same directory as <code>Taskie.exe</code>. Taskie will pick up on the implementation and use it like normal.</p>

<p>This should reduce the usage overhead if you don&#8217;t feel like creating a virtually empty console project in your application, and lower the getting started barrier even more. If you&#8217;d still like to host your own console application for Taskie, that option will continue to be supported and its usage hasn&#8217;t changed.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/jMO1U2xNg-4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/03/04/taskie-runner-is-now-bundled/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/03/04/taskie-runner-is-now-bundled/</feedburner:origLink></item>
		<item>
		<title>Strongly typed client-side URLs in ASP.NET MVC</title>
		<link>http://feeds.mozingo.net/~r/TallerCode/~3/gRe9gEwu2xA/</link>
		<comments>http://darrell.mozingo.net/2011/03/02/strongly-typed-client-side-urls-in-aspnet-mvc/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 03:34:13 +0000</pubDate>
		<dc:creator>Darrell Mozingo</dc:creator>
		
		<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://darrell.mozingo.net/?p=1069</guid>
		<description><![CDATA[The problem

We try to strongly type everything in our MVC project, especially URLs. It&#8217;s pretty easy to do using all the build in functionality of ASP.NET MVC along with some lovin&#8217; from MvcContrib, but the one situation we&#8217;ve always had problems with was client-side javascript. If it&#8217;s a basic action call with no arguments, we&#8217;re [...]]]></description>
			<content:encoded><![CDATA[<h2>The problem</h2>

<p>We try to strongly type everything in our MVC project, especially URLs. It&#8217;s pretty easy to do using all the build in functionality of ASP.NET MVC along with some lovin&#8217; from <a href="http://mvccontrib.codeplex.com/">MvcContrib</a>, but the one situation we&#8217;ve always had problems with was client-side javascript. If it&#8217;s a basic action call with no arguments, we&#8217;re golden (using <code>&lt;%= Html.BuildUrlFromExpression(x =&gt; x.MyAction()) %&gt;</code>). It gets tricky when we have a slightly more complex action though:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>AcceptAjax<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> DoSomethingComplex<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> id, <span style="color: #FF0000;">string</span> accountNumber, <span style="color: #FF0000;">int</span> amount<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">return</span> <span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;id = {0}, accountNumber = {1}, amount = {2}&quot;</span>, id, accountNumber, amount<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>




<p>If we wanted to do an AJAX call to this bad boy, we&#8217;d unfortunately have to resort to string concatenation to build up the URL:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">// get these values from form fields or something...</span>
var id <span style="color: #008000;">=</span> <span style="color: #FF0000;">3</span><span style="color: #008000;">;</span>
var accountNumber <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;123456&quot;</span><span style="color: #008000;">;</span>
var amount <span style="color: #008000;">=</span> <span style="color: #FF0000;">325</span><span style="color: #008000;">;</span>
&nbsp;
var ugly_url <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;/Home/DoSomethingComplex/&quot;</span> <span style="color: #008000;">+</span> id <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;?accountNumber=&quot;</span> <span style="color: #008000;">+</span> accountNumber <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;&amp;amount=&quot;</span> <span style="color: #008000;">+</span> amount<span style="color: #008000;">;</span></pre></td></tr></table></div>




<p>Booo creepy magic strings. Renaming the action name or any of the parameter names left us relying on either ReSharper&#8217;s ability to catch the change, manual search and replace, or hoping we had a UI test hitting the page to catch it. Basically, nothing too terribly reliable to keep our app in working order. The more you worry about small changes breaking your application, the less likely you are to refactor it. The less you refactor, the faster your application degrades into nastiness (code not matching up with current business conventions, etc), and the slower you are to respond to change. Not cool.</p>

<h2>The solution</h2>

<p>Before I go further, I should probably throw up this <b>disclaimer:</b> We use the default routes for everything. The application is behind a login page, and we have no need for fancy SEO friendly URLs, so the solution I&#8217;m about to show caters to that scenario. If your application leverages custom routes, you&#8217;ll either have to tweak this solution to your needs, or figure out something else. Sorry.</p>

<h3>In a nutshell</h3>

<p>You&#8217;ll end up being able to build the URL above like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">var beautiful_url <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;%= Html.UrlTemplate&lt;HomeController&gt;(x =&gt; x.DoSomethingComplex(Any&lt;int&gt;.Arg, Any&lt;string&gt;.Arg, Any&lt;int&gt;.Arg)) %&gt;&quot;</span>
						.<span style="color: #0000FF;">substitute</span><span style="color: #000000;">&#40;</span>id, accountNumber, amount<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>




<p>This&#8217;ll produce a URL template like <code>"/Home/DoSomethingComplex/{0}?accountNumber={1}&#038;amount={2}"</code> on the client. You then plug in the template&#8217;s holes with your client-side values. Pretty simple, really.</p>

<p>There&#8217;s a few server and client-side pieces to this puzzle.</p>

<h3>Server-side portion</h3>

<p>The heart of this solution (and the biggest chuck of code) is the actual building of the URL template.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">bool</span> onlyTakesInSingleViewModel<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> routeValues<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">return</span> <span style="color: #000000;">&#40;</span>routeValues.<span style="color: #0000FF;">Length</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">3</span> <span style="color: #008000;">&amp;&amp;</span> routeValues<span style="color: #000000;">&#91;</span><span style="color: #FF0000;">2</span><span style="color: #000000;">&#93;</span>.<span style="color: #0000FF;">ToLower</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">EndsWith</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;viewmodel&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">string</span> UrlTemplateFor<span style="color: #008000;">&lt;</span>CONTROLLER<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>Expression<span style="color: #008000;">&lt;</span>Action<span style="color: #008000;">&lt;</span>CONTROLLER<span style="color: #008000;">&gt;&gt;</span> action<span style="color: #000000;">&#41;</span> where CONTROLLER <span style="color: #008000;">:</span> Controller
<span style="color: #000000;">&#123;</span>
	var routeValues <span style="color: #008000;">=</span> Microsoft.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0600FF;">Internal</span>.<span style="color: #0000FF;">ExpressionHelper</span>.<span style="color: #0000FF;">GetRouteValuesFromExpression</span><span style="color: #000000;">&#40;</span>action<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	var actionPath <span style="color: #008000;">=</span> <span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;/{0}/{1}&quot;</span>, routeValues<span style="color: #000000;">&#91;</span><span style="color: #666666;">&quot;Controller&quot;</span><span style="color: #000000;">&#93;</span>, routeValues<span style="color: #000000;">&#91;</span><span style="color: #666666;">&quot;Action&quot;</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>routeValues.<span style="color: #0000FF;">Count</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">2</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		var routeValuesKeysArray <span style="color: #008000;">=</span> routeValues.<span style="color: #0000FF;">Keys</span>.<span style="color: #0000FF;">ToArray</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>onlyTakesInSingleViewModel<span style="color: #000000;">&#40;</span>routeValuesKeysArray<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			<span style="color: #0600FF;">return</span> actionPath<span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
&nbsp;
		<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>routeValuesKeysArray<span style="color: #000000;">&#91;</span><span style="color: #FF0000;">2</span><span style="color: #000000;">&#93;</span> <span style="color: #008000;">==</span> <span style="color: #666666;">&quot;id&quot;</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			actionPath <span style="color: #008000;">+=</span> <span style="color: #666666;">&quot;/{0}&quot;</span><span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
		<span style="color: #0600FF;">else</span>
		<span style="color: #000000;">&#123;</span>
			actionPath <span style="color: #008000;">+=</span> <span style="color: #666666;">&quot;?&quot;</span> <span style="color: #008000;">+</span> routeValuesKeysArray<span style="color: #000000;">&#91;</span><span style="color: #FF0000;">2</span><span style="color: #000000;">&#93;</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;={0}&amp;&quot;</span><span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
&nbsp;
		var placeHolderCounter <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>routeValues.<span style="color: #0000FF;">Count</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">3</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>actionPath.<span style="color: #0000FF;">Contains</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;?&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #0600FF;">false</span><span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#123;</span>
				actionPath <span style="color: #008000;">+=</span> <span style="color: #666666;">&quot;?&quot;</span><span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
&nbsp;
			<span style="color: #0600FF;">for</span> <span style="color: #000000;">&#40;</span>var i <span style="color: #008000;">=</span> <span style="color: #FF0000;">3</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> routeValues.<span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#123;</span>
				actionPath <span style="color: #008000;">+=</span> routeValuesKeysArray<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;={&quot;</span> <span style="color: #008000;">+</span> placeHolderCounter<span style="color: #008000;">++</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;}&amp;&quot;</span><span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
		<span style="color: #000000;">&#125;</span>
&nbsp;
		actionPath <span style="color: #008000;">=</span> actionPath.<span style="color: #0000FF;">TrimEnd</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">'&amp;'</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">return</span> actionPath<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>




<p>This method (which has unit tests in the sample project provided at the end of the post) basically builds up the URL template by leaning on a method inside the MVC Futures assembly to get the controller, action, and parameter names. This is the portion you&#8217;d have to tweak if you use different routing rules.</p>

<p>Then it&#8217;s simply a matter of wrapping the UrlBuilder call with an HTML Helper extension method:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">class</span> HtmlHelperExtensions
<span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">string</span> UrlTemplate<span style="color: #008000;">&lt;</span>CONTROLLER<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span> HtmlHelper htmlHelper, Expression<span style="color: #008000;">&lt;</span>Action<span style="color: #008000;">&lt;</span>CONTROLLER<span style="color: #008000;">&gt;&gt;</span> action<span style="color: #000000;">&#41;</span> where CONTROLLER <span style="color: #008000;">:</span> Controller
	<span style="color: #000000;">&#123;</span>
		<span style="color: #0600FF;">return</span> UrlBuilder.<span style="color: #0000FF;">UrlTemplateFor</span><span style="color: #000000;">&#40;</span>action<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>




<p>Looking at the example of using this method above, you can see all the parameters in the <code>UrlTemplate</code> call replaced with calls to an <code>Any</code> class. Technically speaking, whatever values you put in the expression passed to <code>UrlTemplate</code> will be ignored. You can put in nulls for references &amp; nullable types, 0&#8217;s for value types, etc. I decided to drive home the point to anyone looking at the code that we <i>don&#8217;t care</i> what value they provide by making a very slim class that provides the default value for whatever type is needed:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> Any<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> T Arg
	<span style="color: #000000;">&#123;</span>
		get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> <span style="color: #0600FF;">default</span><span style="color: #000000;">&#40;</span>T<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>




<p>It drives home that whole not caring point pretty well, but it&#8217;s also a bit wordy, especially if there&#8217;s 3 or 4 parameters that need specified. You can omit using the <code>Any</code> class and just give dummy values if you want. Your choice.</p>

<h3>Client-side portion</h3>

<p>There&#8217;s not a whole lot to the client-side portion. Basically a very simple version of the .NET Framework&#8217;s <code>string.Format</code> method (which you&#8217;ll probably want to put in an external js file and reference as needed). It&#8217;s written as an extension on the string type to make reading the final product a bit more natural:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">String</span>.<span style="color: #0000FF;">prototype</span>.<span style="color: #0000FF;">replaceAll</span> <span style="color: #008000;">=</span> function <span style="color: #000000;">&#40;</span>patternToFind, replacementString<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">return</span> <span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">replace</span><span style="color: #000000;">&#40;</span><span style="color: #008000;">new</span> RegExp<span style="color: #000000;">&#40;</span>patternToFind, <span style="color: #666666;">&quot;gi&quot;</span><span style="color: #000000;">&#41;</span>, replacementString<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #FF0000;">String</span>.<span style="color: #0000FF;">prototype</span>.<span style="color: #0000FF;">substitute</span> <span style="color: #008000;">=</span> function <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	var formatted <span style="color: #008000;">=</span> this<span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">for</span><span style="color: #000000;">&#40;</span>var i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> arguments.<span style="color: #0000FF;">length</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
		formatted <span style="color: #008000;">=</span> formatted.<span style="color: #0000FF;">replaceAll</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\\</span>{&quot;</span> <span style="color: #008000;">+</span> i <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\\</span>}&quot;</span>, arguments<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">return</span> formatted<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>




<p>That&#8217;s it. Using all these pieces together gives us the final product:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">var beautiful_url <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;%= Html.UrlTemplate&lt;HomeController&gt;(x =&gt; x.DoSomethingComplex(Any&lt;int&gt;.Arg, Any&lt;string&gt;.Arg, Any&lt;int&gt;.Arg)) %&gt;&quot;</span>
						.<span style="color: #0000FF;">substitute</span><span style="color: #000000;">&#40;</span>id, accountNumber, amount<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>




<p>You can provide the values for the URL template from client-side code, or from your ViewModel by just outputting the value in the proper spot (i.e. use <code>&lt;%= Model.Id %&gt;</code> rather than the client-side <code>id</code> property). This setup has proven very helpful and quite versatile for us so far.</p>

<h2>Potential pitfalls</h2>

<p>Having shown all this, there are a few potential pitfalls you need to be aware of:</p>

<ol>
<li>The building of the URL template is pretty rudimentary. It also relies on a method inside the MVC Futures assembly, which I haven&#8217;t checked to see if it even exists in MVC3, let alone in future versions. I couldn&#8217;t find anything in the main MVC assembly or MvcContrib to fill my needs. Having said that, it&#8217;s isolated to one location and we could always get the controller, action, and parameter names by hand with a little expression tree walking, especially since we&#8217;re already limited to the default route setup and therefore know where they&#8217;d be with pretty good certainty.</li>
<li>This allows you to rename controller, action, and parameter names with complete confidence. However, if you switch parameter positions around, especially if they&#8217;re the same type, you might run into a problem. In my usage example above, for instance, switching the <code>id</code> and <code>amount</code> parameters around would still compile and technically run, but the Javascript would continue passing the <code>id</code> in for the <code>amount</code> parameter and vise-versa. You don&#8217;t usually switch around parameters for no reason, but it&#8217;s worth noting, as you&#8217;d have to do a find usages and make sure all the calls are updated properly. At least you&#8217;d be able to find all the usages with certainty, though.</li>
</ol>

<h2>Conclusion</h2>

<p>Next time you find yourself needing to concatenate strings on the client-side to call URLs, think about using this technique (or something similar) to keep it all strongly typed. If you&#8217;re going to work in a static language like C#, you might as well leverage it as much as possible. Strong typing lets you refactor with full confidence that no references to the rename will get left behind by mistake.</p>

<p>You can grab a copy of the source code for the project <a href="https://github.com/DarrellMozingo/Blog/tree/master/StronglyTypedMvcClientSideUrls">right here</a> (built with MVC2). Give it a spin and let me know if you have any problems, or if you know a better way to do this without building the URLs by hand.</p><img src="http://feeds.feedburner.com/~r/TallerCode/~4/gRe9gEwu2xA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://darrell.mozingo.net/2011/03/02/strongly-typed-client-side-urls-in-aspnet-mvc/feed/</wfw:commentRss>
		<feedburner:origLink>http://darrell.mozingo.net/2011/03/02/strongly-typed-client-side-urls-in-aspnet-mvc/</feedburner:origLink></item>
	</channel>
</rss>

