<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0UFSHs4fCp7ImA9WhBQE0Q.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270</id><updated>2013-03-15T17:53:39.534-07:00</updated><category term="Code Katas" /><category term="ASP.NET QA Code Dojo" /><title>Drew's Prog 'Blog</title><subtitle type="html">Wherein Drew records his experiences and thoughts while developing software to save them before they are evicted from his brain's cache.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://drew-prog.blogspot.com/" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/drew-prog" /><feedburner:info uri="drew-prog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEEEQHk7fyp7ImA9Wx9WFEs.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-7540401179250229085</id><published>2011-01-18T12:33:00.000-08:00</published><updated>2011-01-19T11:50:01.707-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-19T11:50:01.707-08:00</app:edited><title>How to Deploy an ASP.NET MVC 3 App to Web Hosting with "\bin Deployment"</title><content type="html">&lt;i&gt;Already know what "/bin deployment" means, and just looking for the list of assemblies you need to include for MVC 3? &lt;a href="#assemblylist"&gt;Skip to the end&lt;/a&gt;.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Since&lt;a href="http://www.asp.net/mvc/mvc3"&gt; ASP.NET MVC 3&lt;/a&gt; was &lt;a href="http://weblogs.asp.net/scottgu/archive/2011/01/13/announcing-release-of-asp-net-mvc-3-iis-express-sql-ce-4-web-farm-framework-orchard-webmatrix.aspx"&gt;released last week&lt;/a&gt;, I've had several folks ask me how they can deploy their MVC 3 apps to a web hosting service. They asked because when they attempted to upload their app's files, they saw this error (or one similar to it):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTVAoBzwV_I/AAAAAAAAADA/fEAEgYNw37s/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="199" src="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTVAoBzwV_I/AAAAAAAAADA/fEAEgYNw37s/s640/Capture.PNG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;What's the Problem?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When you install MVC 3 on your local machine, a number of assemblies are registered in the &lt;a href="http://en.wikipedia.org/wiki/Global_Assembly_Cache"&gt;GAC&lt;/a&gt;. MVC 3 needs these assemblies. Unless your web hosting service has installed MVC 3 on their servers (and many haven't, yet), those assemblies won't be there, and you'll see an error similar to the one above.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What's the Solution?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As with previous versions of MVC, we suggest you solve this with what we call "&lt;a href="http://haacked.com/archive/2008/11/03/bin-deploy-aspnetmvc.aspx"&gt;\bin deployment.&lt;/a&gt;" Bin Deployment is just a fancy term that means "include the MVC assembly (and its dependencies) in your web application's /bin folder." It's not hard to prepare your project for Bin Deployment, but there are a few more assemblies involved compared to MVC 2. I'll show you what you need to do, step by step.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 1: Add Explicit References for MVC and Its Dependencies&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Your MVC app's project probably won't have references to all of the assemblies it needs, because they're in the GAC. So you need to add them. Here is the list (they'll all be available in the .NET tab of the Add Reference dialog):&lt;br /&gt;
&lt;a href="" name="assemblylist"&gt;&lt;ul&gt;&lt;li&gt;Microsoft.Web.Infrastructure&lt;/li&gt;
&lt;li&gt;System.Web.Helpers&lt;/li&gt;
&lt;li&gt;System.Web.Mvc&lt;/li&gt;
&lt;li&gt;System.Web.Razor&lt;/li&gt;
&lt;li&gt;System.Web.WebPages&lt;/li&gt;
&lt;li&gt;System.Web.WebPages.Deployment&lt;/li&gt;
&lt;li&gt;System.Web.WebPages.Razor&lt;/li&gt;
&lt;/ul&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TTXy8sGSldI/AAAAAAAAADE/gt-UYqCec7M/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="254" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TTXy8sGSldI/AAAAAAAAADE/gt-UYqCec7M/s320/Capture.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTXy-Nz6NVI/AAAAAAAAADI/2OcAoHhM6Vg/s1600/Capture2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="254" src="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTXy-Nz6NVI/AAAAAAAAADI/2OcAoHhM6Vg/s320/Capture2.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTc_yRreYLI/AAAAAAAAADU/lMcSWbEvQVA/s1600/Capture3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="254" n4="true" src="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTc_yRreYLI/AAAAAAAAADU/lMcSWbEvQVA/s320/Capture3.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Step 2: Change Each Reference's Copy Local Property to True&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
After adding the references, you need to set the Copy Local property &lt;b&gt;&lt;i&gt;for each of the references you just added&lt;/i&gt;&lt;/b&gt;&amp;nbsp;to True, as pictured below.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TTX1rXYg2KI/AAAAAAAAADQ/DNUX10UHNbA/s1600/Capture5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TTX1rXYg2KI/AAAAAAAAADQ/DNUX10UHNbA/s320/Capture5.PNG" width="198" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Step 3: Re-Build and Deploy as You Normally Would&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Now, when you build your app, the MVC assembly and its dependencies will be copied to the /bin directory, allowing you to deploy as you normally would.&lt;br /&gt;
&lt;br /&gt;
I hope this helps.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;If you have any questions or concerns about this 'blog post, or in general, please send an email to drewmi at microsoft dot com. I'm also on Twitter at &lt;a href="http://twitter.com/anglicangeek"&gt;http://twitter.com/anglicangeek&lt;/a&gt;.&lt;/i&gt;&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/6yVSxSUsclc" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/7540401179250229085?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/7540401179250229085?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/6yVSxSUsclc/how-to-deploy-aspnet-mvc-3-app-to-web.html" title="How to Deploy an ASP.NET MVC 3 App to Web Hosting with &quot;\bin Deployment&quot;" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTVAoBzwV_I/AAAAAAAAADA/fEAEgYNw37s/s72-c/Capture.PNG" height="72" width="72" /><feedburner:origLink>http://drew-prog.blogspot.com/2011/01/how-to-deploy-aspnet-mvc-3-app-to-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMHQns8cSp7ImA9Wx9WEE0.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-3812941985954893146</id><published>2011-01-14T02:18:00.000-08:00</published><updated>2011-01-14T02:20:33.579-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-14T02:20:33.579-08:00</app:edited><title>How To Publish an ASP.NET MVC 3 App to Windows Azure</title><content type="html">With the final, "RTM" version of &lt;a href="http://haacked.com/archive/2011/01/13/aspnetmvc3-released.aspx"&gt;ASP.NET MVC 3 shipping today&lt;/a&gt;, I've had a number of people ask me how to publish an MVC 3 app to Windows Azure. It's a bit more complicated than publishing an MVC 2 app, at least at this time of writing. I'll walk you through the process.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Note&lt;/b&gt;: You need to have installed &lt;a href="http://www.microsoft.com/web/gallery/install.aspx?appid=MVC3"&gt;ASP.NET MVC 3&lt;/a&gt; and &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=7a1089b6-4050-4307-86c4-9dadaa5ed018"&gt;Windows Azure Tools 1.3&lt;/a&gt; to follow this process.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;0. Upgrade Your MVC 2 App&lt;/b&gt;&lt;br /&gt;
If you're starting with an MVC 2 app, you'll need to upgrade it first. I won't describe the upgrade process here, because we've already documented it &lt;a href="http://www.asp.net/learn/whitepapers/mvc3-release-notes#upgrading"&gt;in the release notes&lt;/a&gt;. Also, a couple of the MVC team's developers built &lt;a href="http://blogs.msdn.com/b/marcinon/archive/2011/01/13/mvc-3-project-upgrade-tool.aspx"&gt;an upgrade tool&lt;/a&gt; to make the process easier, so you might try that instead of manually upgrading your app's project.&lt;br /&gt;
&lt;br /&gt;
If you aren't starting from an existing MVC 2 app, just create a new MVC 3 app before moving to the first step.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Create the Windows Azure Project&lt;/b&gt;&lt;br /&gt;
Add a new Windows Azure Project in the same solution as your MVC 3 app. When you see the New Windows Azure Project dialog (pictured below), just click OK without adding any roles.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTAXO3HJIMI/AAAAAAAAACg/ihSoI6wXzBc/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="91" src="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTAXO3HJIMI/AAAAAAAAACg/ihSoI6wXzBc/s320/Capture.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TTAVhR490HI/AAAAAAAAACc/T34VQ2lt9xo/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TTAVhR490HI/AAAAAAAAACc/T34VQ2lt9xo/s320/Untitled.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Why didn't I have you add any roles? Because the 1.3 version of the Azure tools doesn't have support for MVC 3, and therefore it isn't in the list of available web role types. You'll need to add your MVC 3 app after-the-fact, which you'll do in the next step.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Add the MVC 3 App as a Web Role&lt;/b&gt;&lt;br /&gt;
To add your MVC app as an Azure web role, right-click the Roles folder in the Azure project, select Add, then select Web Role Project in solution (as pictured below).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TTAYP0TJQhI/AAAAAAAAACk/LlG1h47Fw1w/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="63" src="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TTAYP0TJQhI/AAAAAAAAACk/LlG1h47Fw1w/s320/Capture.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Your MVC 3 app will be in the list of projects on the next dialog. Select it and click OK. Verify that your MVC 3 app now is listed in the Roles folder.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTAZL4LhSfI/AAAAAAAAACo/eIOY5GEZiCo/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="254" src="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTAZL4LhSfI/AAAAAAAAACo/eIOY5GEZiCo/s320/Capture.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTAZdGp1uQI/AAAAAAAAACs/JG-UGCNOFac/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TTAZdGp1uQI/AAAAAAAAACs/JG-UGCNOFac/s1600/Capture.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
You might think you could publish now, but the role would fail to start because MVC 3 has&amp;nbsp;dependencies&amp;nbsp;that don't exist in the Azure hosted service environment. We'll work around that in the next step.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Prepare Assemblies for "Bin Deployment"&lt;/b&gt;&lt;br /&gt;
The Azure hosted service environment doesn't have MVC 3 installed, so you effectively need to prepare what we call a "bin deployment" for your MVC 3 app, which simply means that MVC and all of the assemblies (DLLs) upon which it depends are bundled (included) with your app, locally in the ~\bin folder.&lt;br /&gt;
&lt;br /&gt;
First, make sure &lt;i&gt;&lt;b&gt;all&lt;/b&gt;&lt;/i&gt; of the following assemblies are added as references to your MVC 3 app (some may already be added as references to your app, but not all of them will):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="MsoNormal"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Microsoft.Web.Infrastructure&lt;/li&gt;
&lt;li&gt;System.Web.Helpers&lt;/li&gt;
&lt;li&gt;System.Web.Mvc&lt;/li&gt;
&lt;li&gt;System.Web.Razor&lt;/li&gt;
&lt;li&gt;System.Web.WebPages&lt;/li&gt;
&lt;li&gt;System.Web.WebPages.Deployment&lt;/li&gt;
&lt;li&gt;System.Web.WebPages.Razor&lt;/li&gt;
&lt;/ul&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TTAgDpR1yOI/AAAAAAAAACw/S44WT6ih_mc/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TTAgDpR1yOI/AAAAAAAAACw/S44WT6ih_mc/s320/Capture.PNG" width="185" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Next, for &lt;i&gt;&lt;b&gt;each&lt;/b&gt;&lt;/i&gt; of those assemblies, open the Properties pane (right-click the reference, then click Properties) and change the Copy Local setting to True.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTAgpDwRJMI/AAAAAAAAAC0/A2EaWSth0n4/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTAgpDwRJMI/AAAAAAAAAC0/A2EaWSth0n4/s320/Capture.PNG" width="283" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Build your solution to check for errors before moving to the next step, which is actually publishing to Azure.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4. Publish as Normal&lt;/b&gt;&lt;br /&gt;
You should now be able to publish your Windows Azure project, which includes your MVC 3 app, as you would normally with any other type of web role.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TTAiUtVkdSI/AAAAAAAAAC8/LrxE0nYrP8M/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TTAiUtVkdSI/AAAAAAAAAC8/LrxE0nYrP8M/s320/Capture.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Note&lt;/b&gt;: I've seen an odd problem, albeit not consistently, when deploying an MVC 3 app to Azure where the role takes a very long time to reach the ready state, after cycling from starting, to stopping, to recycling, and back again several times. If you encounter this problem, you might try stopping the deployment and re-deploying; that seemed to help me.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
I hope this helps.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;If you have any questions or concerns about this 'blog post, or in general, please send an email to me at drewmi &amp;lt;at&amp;gt; microsoft &amp;lt;dot&amp;gt; com. I'm also on Twitter at &lt;a href="http://twitter.com/anglicangeek"&gt;http://twitter.com/anglicangeek&lt;/a&gt;.&lt;/i&gt;&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/00zzGuvBUJ0" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/3812941985954893146?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/3812941985954893146?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/00zzGuvBUJ0/how-to-publish-aspnet-mvc-3-app-to.html" title="How To Publish an ASP.NET MVC 3 App to Windows Azure" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_Gj_YMH4bTVc/TTAXO3HJIMI/AAAAAAAAACg/ihSoI6wXzBc/s72-c/Capture.PNG" height="72" width="72" /><feedburner:origLink>http://drew-prog.blogspot.com/2011/01/how-to-publish-aspnet-mvc-3-app-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAESXg8eSp7ImA9Wx5aFUU.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-5691896782041089503</id><published>2010-11-12T01:38:00.000-08:00</published><updated>2010-11-12T09:41:48.671-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-12T09:41:48.671-08:00</app:edited><title>How to Uninstall Microsoft ASP.NET MVC 3 RC</title><content type="html">&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Scott Guthrie &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/11/11/a-few-quick-asp-net-mvc-3-installation-notes.aspx"&gt;'blogged about some install problems&lt;/a&gt;&amp;nbsp;some folks are having with our &lt;a href="http://haacked.com/archive/2010/11/09/asp-net-mvc-3-release-candidate.aspx"&gt;RC release&lt;/a&gt; of Microsoft &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET MVC 3&lt;/a&gt;. One problem is that MVC 3 and the &lt;a href="http://msdn.microsoft.com/en-us/vstudio/async.aspx"&gt;Async CTP&lt;/a&gt; do not work side-by-side. If you've installed both, you now need to &lt;u&gt;uninstall &lt;/u&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;both&lt;/span&gt; to get back into a state where you can install &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;one or the othe&lt;/span&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;r&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;But uninstalling MVC 3 RC isn't as simple as uninstalling everything labeled 'ASP.NET MVC 3' in Programs and Features. MVC 3 RC also installs ASP.NET Web Pages (upon which it depends), NuGet, and a Visual Studio update that adds tools support for the Razor view engine. So, to completely uninstall MVC 3 RC, you actually need to uninstall &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;all&lt;/span&gt; of the following:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-top: 0px;"&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Microsoft ASP.NET MVC 3&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Microsoft ASP.NET&amp;nbsp;MVC 3&amp;nbsp;- Visual Studio 2010 Tools&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;i&gt;(only installed when you have Visual Studio 2010)&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Microsoft ASP.NET&amp;nbsp;MVC 3&amp;nbsp;- VWD Express&amp;nbsp;2010&amp;nbsp;Tools&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;i&gt;(only installed if you have Visual Web Developer 2010 Express)&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Microsoft ASP.NET Web Pages&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Microsoft ASP.NET Web Pages - Visual Studio 2010 Tools&amp;nbsp;&lt;i&gt;(only installed when you have Visual Studio 2010)&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Microsoft ASP.NET Web Pages - VWD Express&amp;nbsp;2010&amp;nbsp;Tools&amp;nbsp;&lt;i&gt;(only installed if you have Visual Web Developer 2010 Express)&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;NuGet&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Update for Microsoft Visual Studio 2010 &lt;sku&gt; - &lt;loc&gt;&amp;nbsp;(KB2385361)&amp;nbsp;&lt;i&gt;(only installed when you have Visual Studio 2010)&lt;/i&gt;&lt;/loc&gt;&lt;/sku&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Update for Microsoft Visual&amp;nbsp;Web Developer 2010 Express&amp;nbsp;- &lt;loc&gt;&amp;nbsp;(KB2385361)&amp;nbsp;&lt;i&gt;(only installed if you have Visual Web Developer 2010 Express)&lt;/i&gt;&lt;/loc&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;b&gt;N.B.&lt;/b&gt;, the last two are installed as updates, not products; you'll need to switch to the 'View installed updates' section to uninstall them.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;Windows 7 Walk-through&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Here is a step-by-step walk-through of how to completely uninstall ASP.NET MVC 3 RC on Windows 7 (the steps and screens will differ on other versions of Windows, but the the idea, and actions you must take, are essentially the same):&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Open the Control Panel (Click Start, then click Control Panel)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;If you're in Category view, click 'Uninstall a program'; otherwise, click 'Program and Features'&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Uninstall everything that includes the phrase 'ASP.NET MVC 3'&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TN0EriEyl6I/AAAAAAAAACA/n7HTGDopE1M/s1600/1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TN0EriEyl6I/AAAAAAAAACA/n7HTGDopE1M/s320/1.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Uninstall everything that includes the phrase 'ASP.NET Web Pages'&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TN0Ha0OnepI/AAAAAAAAACI/R0rH0LvatPo/s1600/2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="34" src="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TN0Ha0OnepI/AAAAAAAAACI/R0rH0LvatPo/s320/2.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Uninstall 'NuGet'&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TN0Hf19hJMI/AAAAAAAAACM/gm9P6hcbvLA/s1600/3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="39" src="http://4.bp.blogspot.com/_Gj_YMH4bTVc/TN0Hf19hJMI/AAAAAAAAACM/gm9P6hcbvLA/s320/3.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Switch to the 'View installed updates' section&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TN0JIxKgvXI/AAAAAAAAACQ/hUtSff9HOWw/s1600/4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="132" src="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TN0JIxKgvXI/AAAAAAAAACQ/hUtSff9HOWw/s320/4.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Uninstall everything that includes the phrase 'KB2385361'&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TN0JN8Sy60I/AAAAAAAAACU/1A9-eyFHa6E/s1600/5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="128" src="http://3.bp.blogspot.com/_Gj_YMH4bTVc/TN0JN8Sy60I/AAAAAAAAACU/1A9-eyFHa6E/s320/5.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;ASP.NET MVC 3 RC should now be completely uninstalled.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;Automating the Uninstallation&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;If you don't want to take all those manual steps, open a Visual Studio command prompt* &lt;u&gt;with Administrator privilege&lt;/u&gt; and run &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;all&lt;/span&gt; of the following commands (I suggest you copy and paste them):&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;wmic product where name="Microsoft ASP.NET MVC 3" call uninstall&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;
&lt;li&gt;wmic product where name="Microsoft ASP.NET MVC 3 - Visual Studio 2010 Tools" call uninstall&lt;/li&gt;
&lt;li&gt;wmic product where name="Microsoft ASP.NET MVC 3 - VWD Express 2010 Tools" call uninstall&lt;/li&gt;
&lt;li&gt;wmic product where name="Microsoft ASP.NET Web Pages" call uninstall&lt;/li&gt;
&lt;li&gt;wmic product where name="Microsoft ASP.NET Web Pages - Visual Studio 2010 Tools" call uninstall&lt;/li&gt;
&lt;li&gt;wmic product where name="Microsoft ASP.NET Web Pages - VWD Express 2010 Tools" call uninstall&lt;/li&gt;
&lt;li&gt;wmic product where name="NuGet" call uninstall&lt;/li&gt;
&lt;li&gt;msiexec /package {BC0464FA-A0BA-3E38-85BF-DC5B3A401F48} /uninstall {3069D446-63C5-38F4-9D28-41858024419C}&lt;/li&gt;
&lt;li&gt;msiexec /package {85076DFF-7A17-3566-9CC0-488E6E6D4494} /uninstall {3069D446-63C5-38F4-9D28-41858024419C}&lt;/li&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;i&gt;* if you don't know what a Visual Studio command prompt is, or how to open it, I suggest you use the manual steps.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;I hope this helps.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Cheers,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Drew (&lt;a href="http://twitter.com/anglicangeek"&gt;twitter.com/anglicangeek&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/PX7_dBjRUFk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/5691896782041089503/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2010/11/how-to-uninstall-microsoft-aspnet-mvc-3.html#comment-form" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/5691896782041089503?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/5691896782041089503?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/PX7_dBjRUFk/how-to-uninstall-microsoft-aspnet-mvc-3.html" title="How to Uninstall Microsoft ASP.NET MVC 3 RC" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_Gj_YMH4bTVc/TN0EriEyl6I/AAAAAAAAACA/n7HTGDopE1M/s72-c/1.PNG" height="72" width="72" /><thr:total>13</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2010/11/how-to-uninstall-microsoft-aspnet-mvc-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8EQn0_cSp7ImA9Wx9WFE0.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-726489911126763293</id><published>2010-07-02T13:41:00.000-07:00</published><updated>2011-01-18T18:23:23.349-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-18T18:23:23.349-08:00</app:edited><title>Assign Multiple Class Names to an HAML Element</title><content type="html">Let's say you want to convert the following HTML to &lt;a href="http://haml-lang.com/"&gt;HAML&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="html" name="code"&gt;&lt;div class="message ooc"&gt;This is an out-of-character message.&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;
In HAML, instead of joining the class names with spaces, you chain them with dots:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="html" name="code"&gt;%div.message.ooc This is an out-of-character message.
&lt;/pre&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;If you've used HAML for a significant amount of time, you likely already know this. Sadly, as many times as I've used class name chains in HAML, it seems enough time has lapsed that I've forgotten the syntax, and I have to look it up again.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/8zTKW3KIjFg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/726489911126763293/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2010/07/assign-multiple-class-names-to-haml.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/726489911126763293?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/726489911126763293?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/8zTKW3KIjFg/assign-multiple-class-names-to-haml.html" title="Assign Multiple Class Names to an HAML Element" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2010/07/assign-multiple-class-names-to-haml.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMGQnw4fyp7ImA9WxFXFEg.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-3668613927094729873</id><published>2010-05-21T01:43:00.000-07:00</published><updated>2010-05-21T08:40:23.237-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-21T08:40:23.237-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET QA Code Dojo" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Katas" /><title>Kata Two: The Pair Combinator</title><content type="html">&lt;em&gt;This is the second in a &lt;a href="http://drew-prog.blogspot.com/search/label/ASP.NET%20QA%20Code%20Dojo"&gt;series of code katas&lt;/a&gt; prepared for an internal code dojo I host for the ASP.NET QA team. I share it hoping that others will practice it, and then share their own experiences in the comments. What's a code kata? I'll let &lt;a href="http://pragdave.pragprog.com/"&gt;Dave Thomas&lt;/a&gt;, who coined the term,&lt;a href="http://codekata.pragprog.com/2007/01/code_kata_backg.html#more"&gt; explain its meaning&lt;/a&gt;.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;Per&amp;nbsp;request, I will target client-side JavaScript for our first few code katas, so that jQuery (or another JavaScript framework) may be used. While such a target is somewhat limiting, you can easily adapt this kata to other languages, frameworks, or environments.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
I consider &lt;a href="http://www.extremeprogramming.org/rules/pair.html"&gt;pair programming&lt;/a&gt; a fundamental part of the practice of crafting software. It's not as critical to me as, for instance,&amp;nbsp;test-driven development, but I will always pair when possible. While I might&amp;nbsp;not force pairing&amp;nbsp;on&amp;nbsp;an engineering team, I think it's quite reasonable to require some pair programming in the dojo. So I've decided that the dojo's middle hour (of three) will be paired repetitions (and pairing is certainly permissible in the first and last hour as well).&lt;br /&gt;
&lt;br /&gt;
I also encourage the so-called practice of promiscuous pairing,&amp;nbsp;which is&amp;nbsp;changing your pairing partner frequently,&amp;nbsp;after short periods of time.This works very well in a code dojo, thanks to the repetitive nature of code katas. But my experience is that, if you leave pair rotation and combinations up to folks, they tend to stay with their current partner too long. I decided to assign pairs during the middle hour, and that gave me the idea for the second kata: The Pair Combinator.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;The Form&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Write a web page, using&amp;nbsp;only&amp;nbsp;HTML and client-side JavaScript,&amp;nbsp;that takes as input any number of programmer's names and&amp;nbsp;the number of pairings, and&amp;nbsp;produces as output&amp;nbsp;pair combinations, duplicating combinations only when needed..&lt;br /&gt;
&lt;br /&gt;
The manner by which&amp;nbsp;input is captured, and output is displayed, is left to your creativity, provided it can be accomplished in HTML and client-side JavaScript alone.&lt;br /&gt;
&lt;br /&gt;
You &lt;em&gt;may&lt;/em&gt; use a JavaScript library, such as jQuery. You &lt;em&gt;must&lt;/em&gt; practice TDD. You &lt;em&gt;may&lt;/em&gt; ask anyone in the dojo to pair with you; if they aren't already paired, they &lt;em&gt;must&lt;/em&gt; agree.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;The Focus&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
There are&amp;nbsp;several facets of this kata&amp;nbsp;on which you could focus:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;TDD&lt;/li&gt;
&lt;li&gt;The user interface&lt;/li&gt;
&lt;li&gt;The combinatorial algorithm&lt;/li&gt;
&lt;li&gt;Manipulating the page with JavaScript&lt;/li&gt;
&lt;/ul&gt;Of course, you don't have to focus on just one facet, but I found it helpful to be very deliberate and explicit about what I was focusing on for each repetition. Even though this is a relatively small problem (and page), there are many different ways to craft it. I&amp;nbsp;think it's important to focus on that freedom, and the room it affords for iterative improvement. For instance, I've written discussion forums ten or more times during my career, and each time what I produce is better in some way than the last. So focus keenly on how you can improve iteration-to-iteration, in one or more of the facets.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;Repeating the Kata&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
As with all katas, I suggest you delete all the code, both unit tests and product, between repetitions.&lt;br /&gt;
&lt;br /&gt;
I think this kata is a good candidate for a time limit. On the first practice, take as much time as you need to finish. On subsequent repetitions, give yourself&amp;nbsp;less time, and then shave more and more time off the limit until you can't quite finish.&amp;nbsp;&lt;em&gt;(And, as with any timed kata, it's important not to rush, sacrificing the&amp;nbsp;quality of the&amp;nbsp;form and action.)&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Other ideas:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Try a new JavaScript&amp;nbsp;framework, or none at all, for a repetition. &lt;/li&gt;
&lt;li&gt;Try different implementations; not only in code, but also in the user interface (for instance, displaying results in a table versus a list). &lt;/li&gt;
&lt;li&gt;Think about missing features that still stay true to the page's purpose.&lt;/li&gt;
&lt;/ul&gt;Cheers,&lt;br /&gt;
Drew (&lt;a href="http://twitter.com/anglicangeek"&gt;twitter.com/anglicangeek&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;If you practice this kata, please share your experience in the comments.&lt;/em&gt;&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/u-ZEUZ0CMCs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/3668613927094729873/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2010/05/kata-two-pair-combinator.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/3668613927094729873?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/3668613927094729873?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/u-ZEUZ0CMCs/kata-two-pair-combinator.html" title="Kata Two: The Pair Combinator" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2010/05/kata-two-pair-combinator.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUFR3g8eCp7ImA9WxFXFE4.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-7914637067652622570</id><published>2010-05-20T23:22:00.000-07:00</published><updated>2010-05-21T01:23:36.670-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-21T01:23:36.670-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET QA Code Dojo" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Katas" /><title>Kata One: Red, Green, Refactor (or Next Test) in JavaScript</title><content type="html">&lt;i&gt;This is the first in a &lt;a href="http://drew-prog.blogspot.com/search/label/ASP.NET%20QA%20Code%20Dojo"&gt;series of&amp;nbsp;code katas&lt;/a&gt; prepared for an internal code dojo I host for the ASP.NET QA team. I share it hoping that others will practice it, and then share their own experiences in the comments. What's a code kata? I'll let &lt;a href="http://pragdave.pragprog.com/"&gt;Dave Thomas&lt;/a&gt;, who coined the term, &lt;a href="http://codekata.pragprog.com/2007/01/code_kata_backg.html#more"&gt;explain its meaning&lt;/a&gt;.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
As requested,&amp;nbsp;I will target client-side JavaScript for our&amp;nbsp;first&amp;nbsp;few code katas, so that jQuery (or another JavaScript framework) may be used. While such a target is&amp;nbsp;somewhat limiting,&amp;nbsp;you can easily adapt this kata&amp;nbsp;to other languages, frameworks, or environments.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;strong&gt;&lt;em&gt;The Preparation&lt;/em&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Choose a JavaScript unit testing framework&amp;nbsp;to use for this kata, such as jQuery's&amp;nbsp;&lt;a href="http://docs.jquery.com/QUnit"&gt;QUnit&lt;/a&gt;.&amp;nbsp;Have the editor and browser of your choice ready to program client-side (i.e., browser-based)&amp;nbsp;JavaScript.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;The Form&lt;/em&gt;&lt;/strong&gt; &lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
Implement a JavaScript function that&amp;nbsp;ordinalizes&amp;nbsp;a number&amp;nbsp;using &lt;a href="http://www.martinfowler.com/bliki/TestDrivenDevelopment.html"&gt;test-driven development&lt;/a&gt; (TDD). Ordinalizing a number means&amp;nbsp;converting it to its ordinal equivalent; e.g., 1&amp;nbsp;to 1st, 11 to 11th, 42 to 42nd.&amp;nbsp;The function's specification and algorithm&amp;nbsp;is less important than strictly adhering to the red, green, refactor (or next test)&amp;nbsp; continuous cycle of TDD.&amp;nbsp;That cycle is:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Write a failing test that specifies&amp;nbsp;a single&amp;nbsp;behavior of the unit you are developing.&lt;/li&gt;
&lt;li&gt;Write &lt;em&gt;only&amp;nbsp;&lt;/em&gt;enough code in the unit your are developing to make the test&amp;nbsp;pass. Then ensure that all other tests still pass, as well.&lt;/li&gt;
&lt;li&gt;Examine all of the&amp;nbsp;unit's code thus far written. Can it be improved?&amp;nbsp;If so, make a single improvement and then run all of your tests again. Continue making improvements, &lt;em&gt;one at a time&lt;/em&gt;, until you see no more need for improvement.&lt;/li&gt;
&lt;li&gt;Repeat the above steps for the unit's next behavior, starting with a new, failing test.&lt;/li&gt;
&lt;/ol&gt;When I first started practicing TDD,&amp;nbsp;I struggled&amp;nbsp;to&amp;nbsp;determine&amp;nbsp;what tests to write first, or even at all. If you are struggling as&amp;nbsp;I did, I suggest starting with these three tests:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;It will ordinalize 1 to 1st&lt;/li&gt;
&lt;li&gt;It will ordinalize 11 to 11th&lt;/li&gt;
&lt;li&gt;It will throw if the number argument is null&lt;/li&gt;
&lt;/ol&gt;Keep adding tests, one at at time. The kata is complete when you feel you have completely specified (designed) the ordinalize function via unit tests, and all of those unit tests pass.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;The Focus&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
In my&amp;nbsp;early TDD days,&amp;nbsp;I also struggled to&amp;nbsp;write &lt;em&gt;only&lt;/em&gt; enough code to satisfy the&amp;nbsp;current unit test.&amp;nbsp;For instance, imagine&amp;nbsp;I&amp;nbsp;am writing the code to make test #3 above pass. All that is required is: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;if (num === null) { throw "Number is null!"; }&lt;/span&gt;. But&amp;nbsp;I&amp;nbsp;can anticipate&amp;nbsp;that, for instance, an array or string should throw an error, as well. So&amp;nbsp;I'm tempted to write: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;if (typeof(num) !==&amp;nbsp;'number') { throw "num is not a number!"; }&lt;/span&gt;. This would make test #3 pass, but it might come at the expense of writing the other tests. And maybe&amp;nbsp;I'm adding behaviors&amp;nbsp;I won't actually need.&amp;nbsp;(Of course, there comes a time where some generalization and anticipation&amp;nbsp;makes sense, and learning when and how best to generalize is one aspect of mastering TDD.)&lt;br /&gt;
&lt;br /&gt;
As you practice this kata's form, focus on writing only enough code to make the current unit test pass. Make &lt;em&gt;the smallest change that makes sense&lt;/em&gt;. Also focus on completely specifying the ordinalize function's behavior. The first time I practiced this kata I ended with 7 tests; the last time, 18; and, the highest, nearly 30 (which I felt was over-specifying.) Find what works for you, keeping your focus on the quality of the behaviors, and be open to&amp;nbsp;experimenting from repetition to repetition.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;Repeating the Kata&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Repeat this kata 3-5 times each time you practice it.&lt;br /&gt;
&lt;br /&gt;
I suggest that you delete all the code you write, both the unit tests the ordinalize function, between each repetition of this kata. I know the temptation to save&amp;nbsp;your work&amp;nbsp;for reference is strong, but you'll benefit more from focusing on the form and the action&amp;nbsp;of the kata, not the product. It's also&amp;nbsp;much easier&amp;nbsp;to walk a new road when the old road is&amp;nbsp;out of&amp;nbsp;sight, and one of the reasons&amp;nbsp;we repeat katas&amp;nbsp;is to vary the form (within its boundaries).&lt;br /&gt;
&lt;br /&gt;
Deleting the code between repetitions doesn't mean you can't take notes. In fact, I've found that taking notes during the kata can be helpful (albeit sometimes distracting),&amp;nbsp;and after finishing a kata, I usually examine&amp;nbsp;the&amp;nbsp;product&amp;nbsp;after a 5-minute water-cooler break, noting&amp;nbsp;what I liked, what I disliked, and what things I want to&amp;nbsp;consider for&amp;nbsp;future repetitions. Then, I&amp;nbsp;issue the cleansing Cmd+A, Del.&lt;br /&gt;
&lt;br /&gt;
Here are some other ideas to consider when repeating this kata:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Consider adding a time limit to a repetition, such as 10 or 15 minutes&lt;/li&gt;
&lt;li&gt;Change the function to test, keeping the keen focus on the TDD cycle; for instance, instead of an ordinalize function, try an email validator (sans regular expression), a color name to hex converter that uses shortcuts (e.g., red to #f00), or a function that calculates the date of Easter using&amp;nbsp;a &lt;a href="http://en.wikipedia.org/wiki/Computus"&gt;Computus&lt;/a&gt; such as&amp;nbsp;the &lt;a href="http://en.wikipedia.org/wiki/Golden_Number"&gt;Golden Number&lt;/a&gt;; try to choose something you could TDD in 15 minutes&lt;/li&gt;
&lt;li&gt;Compare your unit tests with another programmer's before you delete the code; how do your tests compare? What can you learn from the differences? What can you learn from their unit tests?&lt;/li&gt;
&lt;li&gt;Pair with another programmer, alternating who writes the test and who writes the code to make it pass; how do the unit tests produced while pairing differ from those produced alone?&lt;/li&gt;
&lt;li&gt;Use a different unit testing framework, or perhaps &lt;a href="http://code.google.com/p/jsspec/"&gt;a BDD framework&lt;/a&gt;; how do your tests differ? How was the experience different?&lt;/li&gt;
&lt;li&gt;Don't use a unit test framework at all; this means you'll have to develop a way to run tests, define tests, and report the results; how does this experience compare to using a test framework? Do your tests look different?&lt;/li&gt;
&lt;/ul&gt;Cheers,&lt;br /&gt;
Drew (&lt;a href="http://twitter.com/anglicangeek"&gt;twitter.com/anglicangeek&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;If you practice this kata, please share your experience in the comments.&lt;/em&gt;&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/FmhcLfT1Ybw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/7914637067652622570/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2010/05/kata-one-red-green-refactor-or-next.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/7914637067652622570?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/7914637067652622570?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/FmhcLfT1Ybw/kata-one-red-green-refactor-or-next.html" title="Kata One: Red, Green, Refactor (or Next Test) in JavaScript" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2010/05/kata-one-red-green-refactor-or-next.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMEQH89fyp7ImA9WxFXE04.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-781960501105079875</id><published>2010-05-19T23:34:00.000-07:00</published><updated>2010-05-19T23:36:41.167-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-19T23:36:41.167-07:00</app:edited><title>Stubbing Node Code for TDD</title><content type="html">I've been furiously hacking with &lt;a href="http://github.com/ry/node"&gt;Node&lt;/a&gt; to build &lt;a href="http://campaignnarrative.com/"&gt;Campaign Narrative&lt;/a&gt;, a website for hosting and playing role-playing games online. I'm storing data in &lt;a href="http://mongodb.org/"&gt;MongoDB&lt;/a&gt;, so I'm building a small library to use &lt;a href="http://martinfowler.com/eaaCatalog/repository.html"&gt;the Repository pattern&lt;/a&gt; on top of it. Once I had something that worked, I decided to toss my spike code and do it for real (via &lt;a href="http://www.martinfowler.com/bliki/TestDrivenDevelopment.html"&gt;TDD&lt;/a&gt;). That's when I realized I had a problem.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Problem&lt;/b&gt;&lt;br /&gt;
My repository library uses &lt;a href="http://github.com/christkv/node-mongodb-native"&gt;the node-mongodb-native library&lt;/a&gt;. I need to stub lots of stuff in node-mongodb-native to TDD my repository code. I tried several approaches: changing and extending prototypes, global redefinition, unshifting a folder of stubs into the require paths; none of it worked (or didn't work in a way that made me happy). Because I'd been hacking Ruby very recently, I was approaching the problem from that perspective. Then I wondered, how would I handle this in .NET? I'd use &lt;a href="http://martinfowler.com/articles/injection.html"&gt;dependency injection&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;My Solution&lt;/b&gt;&lt;br /&gt;
I decided to use an (admittedly very crude) form of constructor injection so I could stub my dependencies. Here is an excerpt from my mongodb_repository.js library:&lt;br /&gt;
&lt;pre class="javascript" name="code"&gt;require("lib/prototypes");
exports.MongoDBRepository = function(config, collectionName, deps) {
  var config = config || {};
  config.merge({
    host: "127.0.0.1",
    port: 27017
  });
  
  deps = deps || {
    Server: require('mongodb/connection').Server,
    Db: require('mongodb/db').Db
  };
  
  this.collectionName = collectionName;
  this.server = new deps.Server(config.host, config.port, {});
  this.db = new deps.Db(config.dbName, this.server)
  
  this.db.open(function(){});
};
&lt;/pre&gt;You'll notice the third argument of my constructor function, deps. By wrapping all of my dependencies in this deps object (instead of the typical, module-level &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;var dep = require("dep")&lt;/span&gt;, I can easily pass stubs in for the dependencies in my test code.&lt;br /&gt;
&lt;br /&gt;
Here is an excerpt of application code that creates a repository object, without passing in deps:&lt;br /&gt;
&lt;pre class="javascript" name="code"&gt;var repositoryConfig = {
  host:   process.env['mongodb-host']   || "127.0.0.1",
  port:   process.env['mongodb-port']   || 27017,
  dbName: process.env['mongodb-name']   || "development" 
};

var accountRepo = new Repository(repositoryConfig, "accounts");
&lt;/pre&gt;And here is an excerpt from my spec, which passes in stubs for deps:&lt;br /&gt;
&lt;pre class="javascript" name="code"&gt;the("Repository constructor function", function(will) {

  will("use a default host of 127.0.0.1 if no host is provided", function (done) {
    var stubs = {
      Server: function(host, port, options) {
        assert.equal("127.0.0.1", host);
        done();
      },
      Db: function(dbName, server) {}
    };
    stubs.Db.prototype.open = function(callback){ };    
    new Repository(null, "theCollection", stubs);
  });

});
&lt;/pre&gt;One of the things I really like about this approach is that my tests are that much more intention-revealing, in that it's very clear what is being stubbed. I know it's a small, simple thing, but it makes me happy. I also like that I don't need any special stubbing library.&lt;br /&gt;
&lt;br /&gt;
This approach works just as well with Node's built-in modules. For example, &lt;a href="http://github.com/anglicangeek/willful/blob/master/spec/reporter_spec.js#L26"&gt;I stub the sys module&lt;/a&gt; for the puts function in my &lt;a href="http://github.com/anglicangeek/willful"&gt;Willful&lt;/a&gt; spec'ing framework.&lt;br /&gt;
&lt;br /&gt;
How do you stub with Node? Please share your own approach with me!&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
Drew (&lt;a href="http://twitter.com/anglicangeek"&gt;twitter.com/anglicangeek&lt;/a&gt;)&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/UNnCNu7CG60" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/781960501105079875/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2010/05/stubbing-node-code-for-tdd.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/781960501105079875?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/781960501105079875?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/UNnCNu7CG60/stubbing-node-code-for-tdd.html" title="Stubbing Node Code for TDD" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2010/05/stubbing-node-code-for-tdd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UARXYzeSp7ImA9WxFXE04.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-3153675525937433718</id><published>2010-05-19T23:00:00.000-07:00</published><updated>2010-05-19T23:00:44.881-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-19T23:00:44.881-07:00</app:edited><title>Missing Node crypto Functions on OS X?</title><content type="html">While integrating the &lt;a href="http://github.com/jed/cookie-node"&gt;cookie-node&lt;/a&gt; library into the application framework I've built on top of &lt;a href="http://github.com/ry/node"&gt;Node&lt;/a&gt;, I ran into an unexpected error: the createHmac function was missing from Node's built-in &lt;a href="http://nodejs.org/api.html#crypto-225"&gt;crypto module&lt;/a&gt;. After reading some posts on &lt;a href="http://groups.google.com/group/nodejs"&gt;Node's Google group&lt;/a&gt;, it seemed that it didn't like my openssl build; perhaps it's some issue with the version of openssl that ships with OS X 10.6.&lt;br /&gt;
&lt;br /&gt;
To fix it, I did the following:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;cd /usr/local/src
curl -O http://www.openssl.org/source/openssl-1.0.0.tar.gz
tar -xzvf openssl-1.0.0.tar.gz
cd openssl-1.0.0.tar.gz
./configure --prefix=/usr/local
make
sudo make install
cd your/path/to/node/src
./configure --prefix=/usr/local
make
sudo make install
make test
&lt;/pre&gt;&lt;br /&gt;
(This assumes you're using /usr/local for sources you build, &lt;a href="http://hivelogic.com/articles/using_usr_local"&gt;as some recommend&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;
Interestingly, and frustratingly, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;./configure&lt;/span&gt; for Node still reported that openssl was missing. But &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;make test&lt;/span&gt; reported no failures, and the createHmac (and other missing functions) were now in the crypto module's exports. Yay!&lt;br /&gt;
&lt;br /&gt;
I post this not only so I have it for reference next time (as I re-image my MBP often), but in case someone else encounters this problem.&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
Drew (&lt;a href="http://twitter.com/anglicangeek"&gt;twitter.com/anglicangeek&lt;/a&gt;)&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/r-lKHnzmGjI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/3153675525937433718/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2010/05/missing-node-crypto-functions-on-os-x.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/3153675525937433718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/3153675525937433718?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/r-lKHnzmGjI/missing-node-crypto-functions-on-os-x.html" title="Missing Node crypto Functions on OS X?" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2010/05/missing-node-crypto-functions-on-os-x.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QCQHwzcSp7ImA9WxFXEk0.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-4818276352786327415</id><published>2010-05-18T08:58:00.000-07:00</published><updated>2010-05-18T09:49:21.289-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-18T09:49:21.289-07:00</app:edited><title>Willful, a light-weight spec'ing library for Node</title><content type="html">Last night, I pushed the spec'ing library I made to TDD&amp;nbsp;&lt;a href="http://campaignnarrative.com/"&gt;Campaign Narrative&lt;/a&gt;&amp;nbsp;to &lt;a href="http://github.com/"&gt;Github&lt;/a&gt;. I'm calling it &lt;a href="http://github.com/anglicangeek/willful"&gt;Willful&lt;/a&gt;, well, because it's full of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;will("do this")&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;will("do that")&lt;/span&gt;. If you're a Javascript hacker, and especially if you're a Node hacker, please &lt;a href="http://github.com/anglicangeek/willful"&gt;check it out&lt;/a&gt; and let me know what you think.&lt;br /&gt;
&lt;br /&gt;
Here's an example specification written with Willful:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="javascript" name="code"&gt;require("willful");
var assert = require("assert");

// start a new specification:
the("function I'm spec'ing", function (will) {

  // start a new behavior:
  will("exhibit the behavior I expect", function(done) {
    // test something via Node's built-in assert module
    assert.ok(true)

    // signal that the behavior's verification is done
    done();
  });

  // start a second behavior (this one'll fail)
  will("not exhibit the behavior I expect", function(done) {
    assert.equal(true, false);
    done();
  });

});
&lt;/pre&gt;&lt;br /&gt;
I looked at many different unit testing and spec'ing libraries when I started to TDD my Node app, and none of them made me quite happy enough. &lt;a href="http://github.com/botanicus/minitest.js"&gt;minitest.js&lt;/a&gt; came closest, and the design for Willful was influenced by it.&lt;br /&gt;
&lt;br /&gt;
(&lt;i&gt;Bonus&lt;/i&gt;: If you look at Willful's own specs, you'll see my approach to stubbing dependencies in Node (such as stubbing sys.puts for reporting). I'll write another 'blog post relating how I came to that approach soon.)&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/B_mMnt0VWLk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/4818276352786327415/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2010/05/willful-light-weight-specing-library.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/4818276352786327415?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/4818276352786327415?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/B_mMnt0VWLk/willful-light-weight-specing-library.html" title="Willful, a light-weight spec'ing library for Node" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2010/05/willful-light-weight-specing-library.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMBRX8yfSp7ImA9WxNXE0s.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-1218501194596014968</id><published>2009-09-30T19:17:00.000-07:00</published><updated>2009-09-30T19:17:34.195-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-30T19:17:34.195-07:00</app:edited><title>Using ASP.NET MVC with Windows Azure</title><content type="html">I've been playing with Windows Azure quite a bit lately. Here is a 'blog post that details how to use an ASP.NET MVC website as a Windows Azure web role: &lt;a href="http://blogs.msdn.com/bursteg/archive/2009/05/23/asp-net-mvc-on-windows-azure-asp-net-mvc-web-role.aspx"&gt;ASP.Net MVC on Windows Azure | ASP.Net MVC Web Role&lt;/a&gt;.&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/8O6z2C6_2dY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/1218501194596014968/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2009/09/using-aspnet-mvc-with-windows-azure.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/1218501194596014968?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/1218501194596014968?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/8O6z2C6_2dY/using-aspnet-mvc-with-windows-azure.html" title="Using ASP.NET MVC with Windows Azure" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2009/09/using-aspnet-mvc-with-windows-azure.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAARX46cSp7ImA9WxNSGUU.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-2767890260440078682</id><published>2009-09-03T05:24:00.000-07:00</published><updated>2009-09-03T05:25:44.019-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-03T05:25:44.019-07:00</app:edited><title>ColorCode 1.0 Released!</title><content type="html">Nearly two years ago I started a "slack project" to create a source code colorizer for &lt;a href="http://codeplex.com"&gt;CodePlex&lt;/a&gt; because none of the existing open source options that would work for us had a friendly license. Then, a year ago, I publicly launched &lt;a href="http://colorcode.codeplex.com"&gt;ColorCode&lt;/a&gt; as an open source project. But I didn't actually package the library as a release that people could download. Folks who wanted to use ColorCode had to build it from source themselves.&lt;br /&gt;
&lt;br /&gt;
CodePlex has been using ColorCode throughout that time. And Microsoft's Forums websites have been using ColorCode for six months. There's another team within Microsoft currently building a site that uses ColorCode as well. It's fair to say it's been stable and well-used for quite some time, even without a formal release.&lt;br /&gt;
&lt;br /&gt;
But there were some things I wanted to do before I took the 1.0 step. Forums needed C++ language support. And there were a handful of unresolved bugs. Well, thanks to tonight's insomnia, all that's behind me. &lt;b&gt;I'm happy to announce that &lt;a href="http://bit.ly/1n6KfK"&gt;ColorCode 1.0&lt;/a&gt; is now available on CodePlex.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There are still plenty of features that could be added, but I'd rather let the people using ColorCode drive that. And, of course, there will always be new languages to add (Ruby and Python are high atop my list). But I'm happy with the languages included in 1.0 (HTML, JavaScript, CSS, XML, C#, VB.NET, C++, and ASP.NET).&lt;br /&gt;
&lt;br /&gt;
I send many thanks to the CodePlex team's developers and testers for their contributions, especially Matt Hawley and Rahul Jajoo.&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/K6dU_xOjaEU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/2767890260440078682/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2009/09/colorcode-10-released.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/2767890260440078682?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/2767890260440078682?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/K6dU_xOjaEU/colorcode-10-released.html" title="ColorCode 1.0 Released!" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2009/09/colorcode-10-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMASXs-fSp7ImA9WxNSEEQ.&quot;"><id>tag:blogger.com,1999:blog-185306606329902270.post-2413777270492050289</id><published>2009-08-24T00:03:00.000-07:00</published><updated>2009-08-24T00:20:48.555-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-24T00:20:48.555-07:00</app:edited><title>Record.Exception for Ruby TDD</title><content type="html">I've been working on a Ruby chat server (well, it's actually more of a connection broker for peer-to-peer chat clients) for an upcoming app I'm going to release. TDD is how I roll, but I haven't done much of it in Ruby because the tooling and workflow is so very different than what I'm used to in the .NET world. Today, finally, I settled into a workflow with TextMate and Test::Unit that makes me happy.&lt;br /&gt;
&lt;br /&gt;
I use &lt;a href="http://xunit.codeplex.com/"&gt;xUnit.net&lt;/a&gt; in the .NET world, which was created and is maintained by my friend &lt;a href="http://bradwilson.typepad.com/"&gt;Brad&lt;/a&gt; and my skip-level boss &lt;a href="http://jamesnewkirk.typepad.com/"&gt;Jim&lt;/a&gt;. There is one thing from xUnit.net that I was really missing when using Test::Unit: Record.Exception. Here is a C# example of how Record.Exception can be used:&lt;br /&gt;
&lt;pre class="csharp" name="code"&gt;using System;
using System.Collections.Generic;
using Xunit;

namespace ColorCode.Compilation
{
    public class LanguageRule_Facts
    {
        public class Constructor_Facts
        {
            [Fact]
            public void It_will_throw_when_the_regex_is_null()
            {
                Dictionary&lt;int, string=""&gt; captures = new Dictionary&lt;int, string=""&gt; { { 0, "fnord" } };

                Exception ex = Record.Exception(() =&amp;gt; new LanguageRule(null, captures));

                Assert.IsType&lt;argumentnullexception&gt;(ex);
                Assert.Equal("regex", ((ArgumentNullException)ex).ParamName);
            }
        }
    }
}&lt;/pre&gt;The important thing about Record.Exception is that it allows you to stay true to the 3A pattern (arrange, act, assert), even though you are dealing with an exception. This is pretty important to me. So I threw together a quick and dirty Ruby method to do the same thing:&lt;br /&gt;
&lt;pre class="ruby" name="code"&gt;def record_exception
  begin
    yield if block_given?
    return nil
  rescue Exception =&amp;gt; ex
    return ex
  end
end
&lt;/pre&gt;Yes, it's ridiculously simple. But now I can do this:&lt;br /&gt;
&lt;pre class="ruby" name="code"&gt;require "test/unit"
require "assert"
require "client"

class ClientTests &amp;lt; Test::Unit::TestCase
  def test_init_will_throw_when_io_is_nil
    ex = record_exception do
      client = Client.new(nil, Object.new) 
    end
    
    assert_not_nil(ex)
    assert_equal(ex.to_s, "io must not be nil.")
  end
end
&lt;/pre&gt;This solves the second-most severe pain point I had with Ruby TDD. There are many more yet, and they'll likely be the subject of future 'blog posts.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://twitter.com/anglicangeek"&gt;&lt;span style="font-style: italic;"&gt;http://twitter.com/anglicangeek&lt;/span&gt;&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/drew-prog/~4/zDulVLQsep0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://drew-prog.blogspot.com/feeds/2413777270492050289/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://drew-prog.blogspot.com/2009/08/recordexception-for-ruby.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/2413777270492050289?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/185306606329902270/posts/default/2413777270492050289?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/drew-prog/~3/zDulVLQsep0/recordexception-for-ruby.html" title="Record.Exception for Ruby TDD" /><author><name>Drew Miller</name><uri>http://www.blogger.com/profile/03573525144205530731</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_Gj_YMH4bTVc/S2pMQFB18iI/AAAAAAAAAAw/9lx5d90X6Os/S220/drew_headshot.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://drew-prog.blogspot.com/2009/08/recordexception-for-ruby.html</feedburner:origLink></entry></feed>
