<?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.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Joshua Flanagan</title><link>http://www.lostechies.com/blogs/joshuaflanagan/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JoshuaFlanagan" /><feedburner:info uri="joshuaflanagan" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Error detected while processing vimrc error when using UTF-8 characters in listchars variable</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/h71fu9mC2_I/error-detected-while-processing-vimrc-error-when-using-utf-8-characters-in-listchars-variable.aspx</link><pubDate>Fri, 16 Jul 2010 16:23:57 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:88417</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=88417</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/07/16/error-detected-while-processing-vimrc-error-when-using-utf-8-characters-in-listchars-variable.aspx#comments</comments><description>&lt;p&gt;This error stumped me for a while, and I didn’t find any good answers on Google, so hopefully this can help someone else. I’m running gVim 7.2 on Windows – this information may not apply to other versions/platforms.&lt;/p&gt;  &lt;h3&gt;Problem&lt;/h3&gt;  &lt;p&gt;I’ve been slowly adding more functionality to my vimrc file. Today I learned about the listchars setting, which allows you to choose what placeholders to use when displaying whitespace (taking the tip from &lt;a href="http://items.sjbach.com/319/configuring-vim-right" target="_blank"&gt;Configuring Vim right&lt;/a&gt;). &lt;/p&gt;  &lt;p&gt;For my “trail” setting (spaces at the end of a line), I picked the Middle Dot Unicode character · (U+00B7 or RightAlt+0183). When I saved (:w) and reloaded the new settings (:so ~\_vimrc), the setting took effect with no problem. However, when I closed gVim and re-opened it, I was greeted with the error message “Invalid argument: listchars…”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_09627615.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_thumb_5F00_7404C0AC.png" width="392" height="137" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Solution&lt;/h3&gt;  &lt;p&gt;After much trial an error, I determined that my _vimrc file must be encoded as UTF-8 with Signature. It was previously encoded as UTF-8 (w/o Signature) – which is how gVim encodes the default file. To fix it, I opened _vimrc in my old favorite &lt;a href="http://www.flos-freeware.ch/notepad2.html" target="_blank"&gt;Notepad2&lt;/a&gt;, clicked on the UTF8 in the status bar, selected UTF-8 Signature, and saved the file. The next time I started gVim, there was no error, and my trailing whitespace displayed with the Middle Dot.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;Update&lt;/font&gt;&lt;/strong&gt;: A comment from John Weldon suggested a much simpler solution that you can do with vim (no Notepad2 required).&lt;/p&gt;  &lt;p&gt;(Optional) If it isn’t already UTF-8 (mine was), set the encoding:&lt;/p&gt;  &lt;p&gt;:set fileencoding=utf-8&lt;/p&gt;  &lt;p&gt;Tell vim to store the encoding signature:&lt;/p&gt;  &lt;p&gt;:set bomb&lt;/p&gt;  &lt;p&gt;And of course :w to save the file.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Error+detected+while+processing+vimrc+error+when+using+UTF-8+characters+in+listchars+variable&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f07%2f16%2ferror-detected-while-processing-vimrc-error-when-using-utf-8-characters-in-listchars-variable.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f07%2f16%2ferror-detected-while-processing-vimrc-error-when-using-utf-8-characters-in-listchars-variable.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=88417" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=h71fu9mC2_I:C-aqFoomN3M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/h71fu9mC2_I" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/vim/default.aspx">vim</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/07/16/error-detected-while-processing-vimrc-error-when-using-utf-8-characters-in-listchars-variable.aspx</feedburner:origLink></item><item><title>Linux Re-revisited</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/Uq9P398AhOo/linux-re-revisited.aspx</link><pubDate>Mon, 05 Jul 2010 01:38:55 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:87707</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>14</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=87707</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/07/04/linux-re-revisited.aspx#comments</comments><description>&lt;p&gt;I have long been a Windows user, but I have a habit of installing Linux on a home machine every couple years to give it a chance to grow on me. It had never won me over to become my primary machine for various reasons: installation issues, driver issues, unable to run my games, unable to run the software I depended on, and no apparent advantage over what I was comfortable using. Until now.&lt;/p&gt;  &lt;h3&gt;Motivation&lt;/h3&gt;  &lt;p&gt;A few months ago I had come across a &lt;a href="http://www.railstutorial.org/" target="_blank"&gt;good Ruby on Rails tutorial&lt;/a&gt;, and had started dipping back into Rails on the side. Rails works on Windows, but you always feel like a second class citizen, as there always seem to be a number of tiny workarounds you have to deal with. &lt;/p&gt;  &lt;p&gt;Around the same time, &lt;a href="http://blog.timtyrrell.net/" target="_blank"&gt;Tim Tyrrell&lt;/a&gt; had told me how he installed Linux via &lt;a href="http://wubi-installer.org/" target="_blank"&gt;Wubi&lt;/a&gt;. It allows you to dual-boot into linux, without repartitioning your hard drive (very much like the Windows 7 &lt;a href="http://www.hanselman.com/blog/LessVirtualMoreMachineWindows7AndTheMagicOfBootToVHD.aspx" target="_blank"&gt;boot to VHD feature&lt;/a&gt;), and gives you the ability to uninstall via Windows’ Add/Remove Programs. No commitment required.&lt;/p&gt;  &lt;p&gt;A&amp;#160; month ago this weekend, I attended the &lt;a href="http://texasjavascript.com/" target="_blank"&gt;TXJS&lt;/a&gt; conference, and reminiscent of &lt;a href="http://www.nofluffjuststuff.com/conference/austin/2006/07/home" target="_blank"&gt;NFJS ‘06&lt;/a&gt;, it got me really fired up about the software world outside of my day job. Back in ‘06, it was Ruby on Rails. This year it was &lt;a href="http://nodejs.org/" target="_blank"&gt;node.js&lt;/a&gt;. At the time, node did not run on Windows (the homepage now reports that it runs on Cygwin), and I felt like I was missing out.&lt;/p&gt;  &lt;p&gt;The night I returned from TXJS, I installed Ubuntu 10.04 (via Wubi) on my primary machine. I downloaded the source for node.js, compiled and installed it, and ran my first”hello world” sample. It was all so much easier than I had anticipated. I suddenly felt there was hope for me, that I would be able to participate in this other side of computing that I had avoided for so long.&lt;/p&gt;  &lt;h3&gt;Impressions&lt;/h3&gt;  &lt;p&gt;The only installation/hardware issues I had this time around was trying to get my 2 external monitors working properly when my laptop was docked (and closed). It was incredibly frustrating and led to having to manually edit the xorg.conf – something I had hoped was in linux’s past. The good news is I did get it all working. The other usual suspects, wireless networking and printing, just worked, without any fuss.&lt;/p&gt;  &lt;p&gt;On the plus side, it’s hard to overstate how nice it is to work on an operating system where 99% of the software is free and available via a package manager. To give you a sense, compare the experience of attempting to use the Subversion client on a machine where it has not been installed. From a Windows 7 Command Prompt, and an Ubuntu Terminal window, I typed: svn [enter]&lt;/p&gt;  &lt;p&gt;Windows 7 response: &lt;code&gt;'svn' is not recognized as an internal or external command, operable program or batch file. &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Ubuntu response: &lt;code&gt;The program 'svn' is currently not installed. You can install it by typing: sudo apt-get install subversion &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;This is not some special case for Subversion – I was given a similar response any time I tried to use a program that was not installed. Do I have Mono installed? Type msc [enter] and Ubuntu tells me which package I need to install to get the Mono C# compiler. It is so much easier to stay focused on the task at hand when you don’t have to search for a website, download a file, and click through an installation wizard.&lt;/p&gt;  &lt;p&gt;I’ve been able to do most of my day-to-day tasks without missing a beat. Gmail, Google Reader, and Google Docs had long ago replaced their installed software equivalents in my life. My personal finance software, &lt;a href="http://moneydance.com/" target="_blank"&gt;Moneydance&lt;/a&gt;, can run on Windows and Linux, with the same license. I haven’t used my PC for gaming in years. I currently only boot into Windows for three reasons: upload running data from my Nike+ Sportband (no Linux support in sight), working from home in Visual Studio, and using Windows Live Writer for writing blog posts (although I’m sure I can find an alternative).&lt;/p&gt;  &lt;p&gt;On a somewhat relevant note, the one suggestion from &lt;a href="http://www.pragprog.com/titles/tpp/the-pragmatic-programmer" target="_blank"&gt;The Pragmatic Programmer&lt;/a&gt; where I’ve always felt the weakest was “Use a Single Editor Well”. I can zip around C# code with VS/ReSharper, but I would never consider VS for general purpose text editing. So I usually end up in Notepad2 – a nice tool, but not the type of editor a programmer should rely on. &lt;a href="http://www.vim.org/" target="_blank"&gt;Vim&lt;/a&gt; has been getting a lot of attention lately, and it seemed a reasonable choice to try. I was well aware of Vim’s steep learning curve, and knew I did not want to try and adopt it for C# editing (I already had a good solution for C#, and I don’t think its an area where Vim’s capabilities would shine), but I knew I wouldn’t “get it” unless I used it for real work. I decided I would complete the entire Ruby on Rails tutorial entirely with vim. With a lot of help from a &lt;a href="http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html" target="_blank"&gt;graphical cheat sheet tutorial&lt;/a&gt; and &lt;a href="http://www.swaroopch.com/notes/Vim" target="_blank"&gt;A Byte of Vim&lt;/a&gt;, it has been going surprisingly well. Becoming a competent vim user has made the Linux experience even more rewarding.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Linux+Re-revisited&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f07%2f04%2flinux-re-revisited.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f07%2f04%2flinux-re-revisited.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=87707" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=Uq9P398AhOo:YRQbq_VRvjk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/Uq9P398AhOo" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/07/04/linux-re-revisited.aspx</feedburner:origLink></item><item><title>Using rake under IronRuby</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/cBW62zfaX-Q/using-rake-under-ironruby.aspx</link><pubDate>Mon, 14 Jun 2010 22:22:19 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:86609</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=86609</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/06/14/using-rake-under-ironruby.aspx#comments</comments><description>&lt;h3&gt;Download and install IronRuby&lt;/h3&gt;  &lt;p&gt;Go to &lt;a href="http://ironruby.codeplex.com/"&gt;http://ironruby.codeplex.com/&lt;/a&gt; and click on the Downloads tab. Grab the .zip file that is appropriate for your platform. There is also a Windows Installer, but I don’t know what it does, so I stick with the zip file. Extract it to a folder on your computer – I recommend c:\ironruby. Add c:\ironruby\bin to your path (if you already have a version of ruby installed, I recommend putting IronRuby in the path AFTER your existing ruby).&lt;/p&gt;  &lt;h3&gt;Download and install Rake&lt;/h3&gt;  &lt;p&gt;This is easy, as rubygems comes along with IronRuby. Open a command prompt and type:&lt;/p&gt;  &lt;pre name="code"&gt;igem install rake&lt;/pre&gt;

&lt;p&gt;In your c:\ironruby\bin folder, there are two new files: rake.bat and rake. I made copies of those files and named them irake.bat and irake, respectively. This is completely unnecessary, but helpful if you already have an existing ruby installed. irake will run a script with IronRuby, and rake will run a script with your existing ruby.&lt;/p&gt;

&lt;p&gt;To test it, create a new file named rakefile.rb in a temporary folder. Add the following contents:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:901ba9b8-1c6a-446b-8fe9-9943c5b9a7c7" class="wlWriterSmartContent"&gt;
  &lt;pre class="ruby" name="code"&gt;task :default do
  puts 'hello world'
end&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Open a command prompt to the folder containing that file, and type&lt;font size="3" face="Courier New"&gt; irake&lt;/font&gt;. After an unfortunate pause, you should see the &amp;quot;”hello world” message. You now have a working IronRuby installation that can run rake scripts. If you have another version of ruby installed (and in your path), you can execute the same script by typing &lt;font size="3" face="Courier New"&gt;rake&lt;/font&gt;. You should see that it also (though much more quickly) puts the greeting message on screen.&lt;/p&gt;

&lt;h3&gt;Now for something interesting&lt;/h3&gt;

&lt;p&gt;If you ran the last demo under both versions of ruby, you witnessed the downside of using rake under IronRuby– the slow startup time. However, IronRuby does have one nice big advantage for .NET developers: the ability to easily call your .NET code from the script.&lt;/p&gt;

&lt;p&gt;For example, I recently built a simple website using a Web Application Project, which compiles to a DLL. I wanted to be able to build out the database schema using my Fluent NHibernate configuration. I created a static BuildSchema method that does just that:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Database &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; BuildSchema()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SchemaExport(GetConfiguration()).Create(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Configuration GetConfiguration()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;     {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Fluently.Configure()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;             .Database(MsSqlConfiguration.MsSql2008.ConnectionString(x =&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;             {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;                 x.Database(&lt;span style="color: #006080"&gt;&amp;quot;mydatabse&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;                 x.Server(&lt;span style="color: #006080"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;                 x.TrustedConnection();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;             }))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;             .Mappings(map =&amp;gt; map.AutoMappings.Add(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;             AutoMap&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;             .AssemblyOf&amp;lt;Database&amp;gt;(t =&amp;gt; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Entity).IsAssignableFrom(t))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;             ))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;         .BuildConfiguration();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;     }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I cannot easily execute the DLL from the command-line (to rebuild the database as part of a build script). Normally I would have to create a separate Console application project, which calls BuildSchema from its Main method. However, with IronRuby, I can invoke this method with the following code:&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; desc &lt;span style="color: #006080"&gt;&amp;quot;Generate the database (requires IronRuby)&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; task :db &lt;span style="color: #0000ff"&gt;do&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;   $:.unshift(&lt;span style="color: #006080"&gt;'.\src\MyApp\bin'&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;   require &lt;span style="color: #006080"&gt;'MyApp'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;   MyApp::Database.BuildSchema&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;   puts &lt;span style="color: #006080"&gt;'Database rebuilt'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; end&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Most of this is standard rake code. The interesting bits are in:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Line 3 - Extend $: (the array of paths that ruby searches for files to load) to include the location of my binary. Otherwise, IronRuby will not be able to find any of the assemblies my assembly depends on. &lt;/li&gt;

  &lt;li&gt;Line 4 - Load the libary built from the web application project (MyApp.dll) &lt;/li&gt;

  &lt;li&gt;Line 5 - Invoke the static Database.BuildSchema method &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With IronRuby and Rake, it is trivial to create build script tasks that make use of your existing .NET code. No need to create special task libraries, as you would with NAnt or MSBuild.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Using+rake+under+IronRuby&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f06%2f14%2fusing-rake-under-ironruby.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f06%2f14%2fusing-rake-under-ironruby.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=86609" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=cBW62zfaX-Q:fZ3xZ1yob3E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/cBW62zfaX-Q" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/ruby/default.aspx">ruby</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/06/14/using-rake-under-ironruby.aspx</feedburner:origLink></item><item><title>Austin Code Camp 2010</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/588ppHKbD4Q/austin-code-camp-2010.aspx</link><pubDate>Tue, 11 May 2010 18:09:36 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:79219</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=79219</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/05/11/austin-code-camp-2010.aspx#comments</comments><description>&lt;p&gt;A reminder that &lt;a href="http://codecamp.adnug.org/" target="_blank"&gt;Austin .NET User Group’s Code Camp&lt;/a&gt; is in a couple days – Saturday, May 15 2010. Code Camp is always free, and registration is still open.&lt;/p&gt;  &lt;p&gt;At 9am, I’ll be talking about “Leveraging conventions in .NET”. I’ll be walking through a few examples of how my team establishes and uses conventions in our day-to-day work to help us move fast. &lt;/p&gt;  &lt;p&gt;Some technologies I’ll touch on:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt; – Should give you a good taste of its power, if you aren’t using it yet. There are a few more jQuery sessions at Code Camp so you can dive in deeper if you like what you see.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://fluentnhibernate.org/" target="_blank"&gt;Fluent NHibernate&lt;/a&gt; – even if you haven’t used FNH or NHibernate, you’ll still be able to appreciate the examples&lt;/li&gt;    &lt;li&gt;&lt;a href="http://fubumvc.com/" target="_blank"&gt;FubuMVC&lt;/a&gt; – should also be interesting to ASP.NET MVC developers&lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Austin+Code+Camp+2010&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f05%2f11%2faustin-code-camp-2010.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f05%2f11%2faustin-code-camp-2010.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=79219" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=588ppHKbD4Q:n5VJdhuJTGY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/588ppHKbD4Q" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/05/11/austin-code-camp-2010.aspx</feedburner:origLink></item><item><title>Adding git commit information to your assemblies</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/_Kyj1yDYVeM/adding-git-commit-information-to-your-assemblies.aspx</link><pubDate>Thu, 08 Apr 2010 04:07:51 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:77192</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=77192</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/04/08/adding-git-commit-information-to-your-assemblies.aspx#comments</comments><description>&lt;h3&gt;The problem&lt;/h3&gt;  &lt;p&gt;It is a fairly common practice of .NET projects hosted in Subversion to include the repository Revision number as part of the AssemblyVersion. For example, MyWidgets.dll might have a version of 1.2.0.5309, which means it was built from the snapshot of source code at revision 5309. This can be very valuable, as it makes it very easy to trace a binary in the wild back to its original source.&lt;/p&gt;  &lt;p&gt;Many projects are now moving towards distributed version control systems (DVCS),&amp;#160; like git, which do not use a simple counter to describe a commit. In git, each commit is represented by a SHA1 hash, which looks something like e5f08d4a9e15943a64014329bd6fd2f348a89b15. Assembly versions in .NET are made up of four 16-bit integers, so it is obvious we cannot include the SHA1 of a commit. We need another way to get a unique number.&lt;/p&gt;  &lt;h3&gt;A solution&lt;/h3&gt;  &lt;p&gt;The solution I’ve been using is to take advantage of the “number of commits since the most recent tag”, as made available through the &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-describe.html" target="_blank"&gt;git describe&lt;/a&gt; command. In order for this to work, you must have at least one tag in your repository. Every time you change the major or minor components of your version, you should create a new tag for that commit. I’ll start by marking commit e5f08d4a9e15943a64014329bd6fd2f348a89b15 as version 1.2.0 (notice I leave off the last version component, as that is the number we will generate):&lt;/p&gt; &lt;code&gt;$ git tag v1.2.0 e5f08d&lt;/code&gt;   &lt;p&gt;(Note: tags are not pushed to remotes, by default. Whenever you create a tag that you wish to make public, you must use the --tags flag when you push. See the &lt;a href="http://progit.org/book/ch2-6.html" target="_blank"&gt;Sharing Tags section in Pro Git&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;I can now use the describe command like this:&lt;/p&gt; &lt;code&gt;$ git describe --tags --long&lt;/code&gt;   &lt;p&gt;which will output:&lt;/p&gt; &lt;code&gt;v1.2.0-&lt;strong&gt;115&lt;/strong&gt;-g4642f26&lt;/code&gt;   &lt;p&gt;The --tags flag allows me to use lightweight tags, and the --long flag makes sure the output is always in the same format. In this example, the number 115 is what we are looking for. That means there have been 115 commits since the most recent tag, which is v1.2.0. The characters after the “g” make up the short version of the current commit’s SHA1. Now its just a simple matter of parsing the describe output so that we can use the number in our assembly version.&lt;/p&gt;  &lt;h3&gt;An example&lt;/h3&gt;  &lt;p&gt;You can see a real world example in &lt;a href="http://github.com/DarthFubuMVC/fubumvc/blob/4bdfd6be1280c700c9f57112eafe7be50ebd7474/rakefile.rb" target="_blank"&gt;FubuMVC build script&lt;/a&gt;. It is a rake (ruby) script that uses the assemblyinfo task from &lt;a href="http://albacorebuild.net/" target="_blank"&gt;Albacore&lt;/a&gt; to generate a CommonAssemblyInfo.cs file at build time, which is referenced by all of the projects in the solution. The relevant section is:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:0ce3b7ec-e04c-4d48-add2-359bfd4bca41" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="ruby:firstline[21]"&gt;desc "Update the version information for the build"
assemblyinfo :version do |asm|
  asm_version = BUILD_NUMBER_BASE + ".0"
  
  begin
	gittag = `git describe --long`.chomp 	# looks something like v0.1.0-63-g92228f4
    gitnumberpart = /-(\d+)-/.match(gittag)
    gitnumber = gitnumberpart.nil? ? '0' : gitnumberpart[1]
    commit = (ENV["BUILD_VCS_NUMBER"].nil? ? `git log -1 --pretty=format:%H` : ENV["BUILD_VCS_NUMBER"])
  rescue
    commit = "git unavailable"
    gitnumber = "0"
  end
  build_number = "#{BUILD_NUMBER_BASE}.#{gitnumber}"
  tc_build_number = ENV["BUILD_NUMBER"]
  puts "##teamcity[buildNumber '#{build_number}-#{tc_build_number}']" unless tc_build_number.nil?
  asm.trademark = commit
  asm.product_name = "#{PRODUCT} #{gittag}"
  asm.description = build_number
  asm.version = asm_version
  asm.file_version = build_number
  asm.custom_attributes :AssemblyInformationalVersion =&amp;gt; asm_version
  asm.copyright = COPYRIGHT
  asm.output_file = COMMON_ASSEMBLY_INFO
end
&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Lines 26-27: run the git describe the command, parse the output with a regular expression, and store it in the gitnumberpart variable&lt;/li&gt;

  &lt;li&gt;Line 29: store the full git commit SHA1 number in the commit variable (either using an environment variable available on the build server, or from the git log command)&lt;/li&gt;

  &lt;li&gt;Lines 31-32: just in case the machine running the build does not have the git client installed&lt;/li&gt;

  &lt;li&gt;Line 34: create the full version number by concatenating the BUILD_NUMBER_BASE variable with the gitnumber from describe. BUILD_NUMBER_BASE can either be hardcoded in the rake script, or read from a VERSION file. It contains the first 3 components of the version (ex: 1.2.0)&lt;/li&gt;

  &lt;li&gt;Lines 35-36: We rewrite our &lt;a href="http://teamcity.codebetter.com/viewType.html?buildTypeId=bt24&amp;amp;tab=buildTypeStatusDiv" target="_blank"&gt;TeamCity build number&lt;/a&gt; to be the assembly version number followed by the sequence number provided by TeamCity (ex: #1.2.0.115-#330, where 330 is the sequence number from TC)&lt;/li&gt;

  &lt;li&gt;Line 37: We store the full commit SHA1 in the AssemblyTrademark attribute. We use this within the FubuMVC diagnostics pages to provide a link to the github page for the currently executing version of the framework.&lt;/li&gt;

  &lt;li&gt;Line 38: We append the full output of the describe command to the product name and store in AssemblyProduct (ex: FubuMVC v1.2.0-115g4642f26)&lt;/li&gt;

  &lt;li&gt;Lines 40-42: We write the various version attributes. Notice the AssemblyVersion attribute always uses zero for the last component of the version, instead of the ever increasing “commits since tag” number. This is on purpose, since AssemblyVersion is used as part of the assembly name, and should not change unless there are breaking changes. We only adjust the version on every build for AssemblyFileVersion, which is not used by .NET at all, but is visible within the File Properties dialog in Windows Explorer.&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Adding+git+commit+information+to+your+assemblies&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f04%2f08%2fadding-git-commit-information-to-your-assemblies.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f04%2f08%2fadding-git-commit-information-to-your-assemblies.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=77192" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=_Kyj1yDYVeM:rLoBvN0TjgQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/_Kyj1yDYVeM" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/teamcity/default.aspx">teamcity</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/git/default.aspx">git</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/04/08/adding-git-commit-information-to-your-assemblies.aspx</feedburner:origLink></item><item><title>Teaching AutoMapper about our conventions</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/wTn7xhV8pTg/teaching-automapper-about-our-conventions.aspx</link><pubDate>Fri, 19 Mar 2010 19:32:04 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:75502</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=75502</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/03/19/teaching-automapper-about-our-conventions.aspx#comments</comments><description>&lt;p&gt;I often need to send data from my entities to the client in JSON format to enable rich AJAX functionality. It isn’t practical to serialize the entities directly, so they are first flattened to a data transfer object (DTO) before serialization. For example, the Case entity has a reference to a Contact entity, which has a FirstName property. On the Case DTO, I might have a ContactFirstName property to hold that value. We use &lt;a href="http://www.codeplex.com/AutoMapper" target="_blank"&gt;AutoMapper&lt;/a&gt; to handle the chore of populating the properties of the DTO using values from the original entity.&lt;/p&gt;  &lt;h3&gt;Conventions for mapping our DTOs&lt;/h3&gt;  &lt;p&gt;AutoMapper requires that we declare up front which which entities will be mapped to which DTOs. It has a lot of intelligent defaults, so once we tell it that a Case can be mapped to a CaseDTO, it can figure out how to populate the ContactFirstName property on the DTO from Case.Contact.FirstName. However, there are some properties on the DTO which aren’t so straightforward, so we have to explicitly configure how they are mapped.&lt;/p&gt;  &lt;p&gt;Our DTOs generally follow these rules:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;For every entity reference property on the source entity, the DTO will have a property of the same name, but of type GUID, which holds the entity identifier. Ex: Case.Contact of type Contact maps to CaseDTO.Contact of type GUID.&lt;/li&gt;    &lt;li&gt;For every entity reference property on the source entity, the DTO will have a property with the name plus the suffix “ViewURL”, which holds the URL for viewing the referenced entity. Ex: CaseDTO.ContactViewUrl holds the URL for the Case.Contact.&lt;/li&gt;    &lt;li&gt;For every “list value” (think values that show in a drop-down) property on the source entity, the DTO will have a property with the name plus the suffix “Display”, which holds the localized display value. Ex: Case.Contact.Country will map the value “USA” to CaseDTO.ContactCountry, and the value “United States” to CaseDTO.ContactCountryDisplay.&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Implementing our mapping rules with AutoMapper&lt;/h3&gt;  &lt;p&gt;It was very easy to teach AutoMapper about the first rule. It took just a single line of code in our configuration:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:109f973c-e8a8-49f0-a7ff-fba5fe91dff4" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;cfg.CreateMap&amp;lt;Entity, Guid&amp;gt;().ConvertUsing(entity =&amp;gt; entity.Id);&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This tells Automapper that any time it tries to map a property of a type that derives from Entity to a property of type GUID, execute the lambda to get the Id.&lt;/p&gt;

&lt;p&gt;The other two rules were not so easy to apply. AutoMapper currently has no built-in support for defining conventions to build mappings based on aspects of the types or their properties (although I hear this is something being considered for the future). Instead, you have to explicitly declare the custom relationship between each type, and each custom property resolution. You end up with code that looks like this:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:96acfb78-61ea-4c9a-a9bd-b955a60fc0af" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;Mapper.Initialize(cfg =&amp;gt;
{
    cfg.CreateMap&amp;lt;Entity, Guid&amp;gt;().ConvertUsing(entity =&amp;gt; entity.Id);
    cfg.CreateMap&amp;lt;Case, CaseDTO&amp;gt;()
        .ForMember(d =&amp;gt; d.ContactViewUrl, map =&amp;gt; map.ResolveUsing&amp;lt;UrlValueResolver&amp;gt;().FromMember(s =&amp;gt; s.Contact))
        .ForMember(d =&amp;gt; d.SiteViewUrl, map =&amp;gt; map.ResolveUsing&amp;lt;UrlValueResolver&amp;gt;().FromMember(s =&amp;gt; s.Site))
        .ForMember(d =&amp;gt; d.InstalledPartViewUrl, map =&amp;gt; map.ResolveUsing&amp;lt;UrlValueResolver&amp;gt;().FromMember(s =&amp;gt; s.InstalledPart))
        // ... and the rest of the ViewUrl properties
        .ForMember(d =&amp;gt; d.CaseTypeDisplay, map =&amp;gt; map.ResolveUsing&amp;lt;ListValueResolver&amp;gt;().FromMember(s =&amp;gt; s.CaseType))
        .ForMember(d =&amp;gt; d.StatusDisplay, map =&amp;gt; map.ResolveUsing&amp;lt;ListValueResolver&amp;gt;().FromMember(s =&amp;gt; s.Status))
        // ... and the rest of the Display properties
        ;
    cfg.CreateMap&amp;lt;Site, SiteDTO&amp;gt;()
        .ForMember(d =&amp;gt; d.SupportSiteViewUrl, map =&amp;gt; map.ResolveUsing&amp;lt;UrlValueResolver&amp;gt;().FromMember(s =&amp;gt; s.SupportSite))
        // ... and the rest of the ViewUrl properties
        .ForMember(d =&amp;gt; d.PrimaryAddressCountryDisplay, map =&amp;gt; map.ResolveUsing&amp;lt;ListValueResolver&amp;gt;().FromMember(s =&amp;gt; s.PrimaryAddress.Country))
        // ... and the rest of the Display properties
        ;
    cfg.CreateMap&amp;lt;Part, PartDTO&amp;gt;()
        // ... all of the ViewUrl properties
        // ... all of the Display properties
        ;
    // ... and the rest of the Entities
});
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The sample is abbreviated because showing all of the entities, and all of the ViewUrl and Display property mappings for each of those entities is just too repetitive to be interesting. Aside from the tedium of having to type it up the first time, it makes maintenance a lot more painful. Any time we add an entity or list value property to an entity, we would have to remember to go add the corresponding mapping to the AutoMapper configuration, or risk introducing bugs.&lt;/p&gt;

&lt;h3&gt;Declaring mapping rule conventions&lt;/h3&gt;

&lt;p&gt;The benefit of establishing conventions in your code is that different parts of the system can rely on those conventions, so you get a lot of functionality that just works the way you would expect. Since we consistently name our DTOs the same way, and we consistently name properties on the DTO the same way, we should be able to rely on the fact that these will always be populated the same way.&lt;/p&gt;

&lt;p&gt;With a couple patches to AutoMapper (now available in the &lt;a href="http://github.com/jbogard/automapper" target="_blank"&gt;latest source&lt;/a&gt;), I was able to build some extension methods that allowed me to express our conventions. The previous (which had to be edited for length) code can now be rewritten as:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:3124e790-bf8d-4984-90c1-e0e81af0cd2e" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;Mapper.Initialize(cfg =&amp;gt;
{
    cfg.CreateMap&amp;lt;Entity, Guid&amp;gt;().ConvertUsing(entity =&amp;gt; entity.Id);
    cfg.CreateMapsForSourceTypes(x =&amp;gt; x.CanBeCastTo&amp;lt;Entity&amp;gt;(),
        type =&amp;gt; Type.GetType(typeof (ListItemMethodDTO).Namespace + "." + type.Name + "DTO"),
        (map, source, destination) =&amp;gt;
        {
            map.MapViewUrls(source, destination);
            map.MapDisplayValues(source, destination);
        });
});&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now the code expresses our convention: for every type that derives from Entity, map it to a type (in a given namespace) with the same name with a DTO suffix, and map all the ViewUrl and Display members appropriately.&lt;/p&gt;

&lt;p&gt;I’ve posted the &lt;a href="http://gist.github.com/338069" target="_blank"&gt;full source for our extension methods&lt;/a&gt;, but the CreateMapsForSourceTypes method is probably the only one that is generally applicable:&lt;/p&gt;

&lt;p&gt;
  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d56ae3ea-04df-45a6-ab4c-5b1d06f05530" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public static void CreateMapsForSourceTypes(this IConfiguration configuration, Func&amp;lt;Type, bool&amp;gt; filter, Func&amp;lt;Type, Type&amp;gt; destinationType, Action&amp;lt;IMappingExpression, Type, Type&amp;gt; mappingConfiguration)
{
    var typesInThisAssembly = typeof (AutoMapperExtensions).Assembly.GetExportedTypes();
    CreateMapsForSourceTypes(configuration, typesInThisAssembly.Where(filter), destinationType, mappingConfiguration);
}

public static void CreateMapsForSourceTypes(this IConfiguration configuration, IEnumerable&amp;lt;Type&amp;gt; typeSource, Func&amp;lt;Type, Type&amp;gt; destinationType, Action&amp;lt;IMappingExpression, Type, Type&amp;gt; mappingConfiguration)
{
    foreach (var type in typeSource)
    {
        var destType = destinationType(type);
        if (destType == null) continue;
        var mappingExpression = configuration.CreateMap(type, destType);
        mappingConfiguration(mappingExpression, type, destType);
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;It simply takes a criteria for identifying your source types, a function for determining the destination type based on the source type, and a set of configuration steps that should be applied to each mapping. Goodbye repetitive code!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Teaching+AutoMapper+about+our+conventions&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f03%2f19%2fteaching-automapper-about-our-conventions.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f03%2f19%2fteaching-automapper-about-our-conventions.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=75502" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=wTn7xhV8pTg:HloZvsHPzcc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/wTn7xhV8pTg" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/automapper/default.aspx">automapper</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/conventions/default.aspx">conventions</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/03/19/teaching-automapper-about-our-conventions.aspx</feedburner:origLink></item><item><title>Adding variable output behavior to your FubuMVC actions</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/jzhqrfliYnU/adding-variable-output-behavior-to-your-fubumvc-actions.aspx</link><pubDate>Mon, 08 Feb 2010 03:34:34 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:61569</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=61569</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/02/07/adding-variable-output-behavior-to-your-fubumvc-actions.aspx#comments</comments><description>&lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;A question I’ve received multiple times now when discussing &lt;a href="http://fubumvc.com/" target="_blank"&gt;FubuMVC&lt;/a&gt;’s flexibility: can I make a single controller action render a view, or json, or rss/xml, etc., based on a request header, or some portion of the URL? The short answer is yes, of course, as I imagine it is for just about any web framework. The more interesting questions are around how difficult it will be, how much code do you have to write (and therefore, maintain), and how invasive it will be to the rest of your design. In this post, I’ll demonstrate one potential solution to the problem, and hopefully answer those questions in a way that reflects positively on FubuMVC. All of the code in this post is available in the Ouptuts/VaryByAcceptHeader solution in the &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/tree/7c4b2165aedb6754a01538aee956e29d4060654c" target="_blank"&gt;fubumvc-examples&lt;/a&gt; repository.&lt;/p&gt;  &lt;p&gt;I’m going to return to my simple sample application which I discussed in &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/01/18/fubumvc-define-your-actions-your-way.aspx" target="_blank"&gt;my last FubuMVC post&lt;/a&gt;. It allows a user to make a list of movies they want to see. Originally, the movies/list action simply rendered a view to display the current list of movies, as well as a form to add more. I’m going to modify this action so that it can also return the list of movies as json or xml.&lt;/p&gt;  &lt;h3&gt;Behaviors&lt;/h3&gt;  &lt;p&gt;FubuMVC has a great mechanism for adding behavior to actions. We creatively call them Behaviors. A Behavior is just a class that contributes to fulfilling a request for a given route. For example, the movies/list route is currently fulfilled by executing two behaviors: OneInOutOutActionInvoker and RenderFubuWebFormView. To solve the given problem, I’m going to introduce a new Behavior: &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/7c4b2165aedb6754a01538aee956e29d4060654c/src/Outputs/VaryByAcceptHeader/SimpleWebsite/Behaviors/RenderVariableOutput.cs" target="_blank"&gt;RenderVariableOutput&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;RenderVariableOutput is fairly straightforward. It has two dependencies that are injected by the container: the IFubuRequest, and an instance of a ConditionOutput. The IFubuRequest contains all of the information about the request, giving me access to the HTTP headers and query string values. ConditionalOutput is a simple helper class that makes it easy for me to associate a predicate and a Behavior, and store them together in the container. It also holds a reference to another ConditionalOutput which it will pass control to if its own predicate fails. The RenderVariableOutput Behavior effectively gets a chain of these ConditionalOutputs, so that when it calls GetOutputBehavior, it will receive the Behavior for the first predicate that passed. If a matching Behavior is found, it is executed.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8c271bad-6540-4932-8f2f-05ad1cec1292" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:firstline[20]"&gt;protected override DoNext performInvoke()
{
    var detector = _fubuRequest.Get&amp;lt;OutputFormatDetector&amp;gt;();

    var behavior = _outputs.GetOutputBehavior(detector);
    if (behavior != null)
    {
        behavior.Invoke();
    }
    return DoNext.Continue;
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The other class you see in play is OutputFormatDetector. It is passed as to the predicates to determine which Behavior to use. This is a simple class that has two properties: Accept, and RenderFormat. The IFubuRequest has access to the same mechanism that is used for model binding. This means that when I ask it for an instance of an OutputFormatDetector (or any class), it will attempt to create a new instance of the class, and then populate the public properties with any values that it knows about. The Accept property will be populated with the value in the Accept HTTP request header. The RenderFormat property will be populated if it finds a value with that key – possibly from the query string, form post data, route parameters, etc.&lt;/p&gt;

&lt;h3&gt;Conventions&lt;/h3&gt;

&lt;p&gt;I now have a Behavior that can execute one of many potential output Behaviors, based on the Accept header or a RenderFormat parameter. There are two remaining tasks: declare the conditions for each potential output, and declare which routes should be able to render different formats.&lt;/p&gt;

&lt;p&gt;One way to associate a Behavior with a route is by creating a Convention. A Convention in FubuMVC is a class that implements IConfigureAction. It has a single method, Configure(), which gives it access to the BehaviorGraph. The BehaviorGraph is the semantic model that represents everything needed to satisfy all of the routes in the application. By manipulating the BehaviorGraph, you can modify how each route is fulfilled.&lt;/p&gt;

&lt;p&gt;For my sample application, I’m going to declare the following convention:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Apply the RenderVariableOutput behavior to every action (route) that returns an IEnumerable model, and is currently configured to render a view.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Note that this is just the convention I picked for this sample. The Behavior itself does not require an IEnumerable output model, I could have just as easily stated “every action that starts with the letter ‘G’. IEnumerable just seemed like good indicator of the kind of data someone might want to see in JSON or XML format.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I implemented this convention in a class named &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/7c4b2165aedb6754a01538aee956e29d4060654c/src/Outputs/VaryByAcceptHeader/SimpleWebsite/Behaviors/VariableOutputConvention.cs" target="_blank"&gt;VariableOutputConvention&lt;/a&gt;. The convention also declares the conditions that would trigger the different outputs:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:82a543b5-f82e-4151-aef5-e7010de42552" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:firstline[26]"&gt;variableOut.AddOutput(a =&amp;gt; a.RenderFormat == "json", json);
variableOut.AddOutput(a =&amp;gt; a.RenderFormat == "xml", xml);
variableOut.AddOutput(a =&amp;gt; a.AcceptsFormat("text/html"), view);
variableOut.AddOutput(a =&amp;gt; a.AcceptsFormat("application/xml"), xml);
variableOut.AddOutput(a =&amp;gt; a.AcceptsFormat("application/json"), json);&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It uses the RenderFormat parameter as a manual override mechanism, before falling back to the Accept header. This allows me to test the behavior by appending a “?RenderFormat=json” query string, since it is more difficult to manipulate the Accept header sent by a browser.&lt;/p&gt;

&lt;p&gt;As a final step, I apply the convention to my application by adding the following line to &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/7c4b2165aedb6754a01538aee956e29d4060654c/src/Outputs/VaryByAcceptHeader/SimpleWebsite/SimpleWebsiteFubuRegistry.cs" target="_blank"&gt;my FubuRegistry&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;ApplyConvention&amp;lt;VariableOutputConvention&amp;gt;(); &lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;See it in action&lt;/h3&gt;

&lt;p&gt;We’ve created the Behavior and tied it to some routes. To see it in action:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Run the website from the sample code and go to &lt;a href="http://localhost:59187/movies/list"&gt;http://localhost:59187/movies/list&lt;/a&gt;. Note that it renders a view, as it used to. &lt;/li&gt;

  &lt;li&gt;Add a few movies to the list. &lt;/li&gt;

  &lt;li&gt;Go to &lt;a href="http://localhost:59187/movies/list?renderformat=json"&gt;http://localhost:59187/movies/list?renderformat=json&lt;/a&gt;. You should see the list in JSON format.&lt;/li&gt;

  &lt;li&gt;Go to &lt;a href="http://localhost:59187/movies/list?renderformat=xml"&gt;http://localhost:59187/movies/list?renderformat=xml&lt;/a&gt;. You should see the list, serialized as XML.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;As you can see, adding multiple output capability to a web application built on FubuMVC is not very hard. The hardest part was in trying to figure out how to represent the predicates and their output behaviors in the semantic model so that they would flow out of the container properly. Beyond that, the functionality is implemented entirely in a few small classes.&lt;/p&gt;

&lt;p&gt;The best part is how I was able to implement this new functionality without impacting the rest of my application design. I added a new capability to existing actions (well, one action in this example, but it could have applied to multiple actions, if more existed that matched the criteria) without changing the actions &lt;em&gt;at all&lt;/em&gt;. I just applied a new &lt;em&gt;behavior &lt;/em&gt;to the action. With a little work (for example, make the list of conditions/outputs configurable via a DSL), the code could be packaged up and re-used across multiple projects. You could just add an assembly to your application project, wire up the convention in your FubuRegistry, and enjoy the new functionality. Hopefully this helped demonstrate the power of FubuMVC’s conventionally applied behaviors.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Adding+variable+output+behavior+to+your+FubuMVC+actions&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f02%2f07%2fadding-variable-output-behavior-to-your-fubumvc-actions.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f02%2f07%2fadding-variable-output-behavior-to-your-fubumvc-actions.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=61569" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=jzhqrfliYnU:9AAC4_yu4Fc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/jzhqrfliYnU" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/fubumvc/default.aspx">fubumvc</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/02/07/adding-variable-output-behavior-to-your-fubumvc-actions.aspx</feedburner:origLink></item><item><title>How to resolve a binary file conflict with Git</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/uWIxK1oRfjg/how-to-resolve-a-binary-file-conflict-with-git.aspx</link><pubDate>Fri, 29 Jan 2010 03:47:35 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:53018</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=53018</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/01/28/how-to-resolve-a-binary-file-conflict-with-git.aspx#comments</comments><description>&lt;p&gt;When performing a merge in &lt;a href="http://git-scm.com/" target="_blank"&gt;git&lt;/a&gt;, you might see the message:&lt;/p&gt;&lt;pre&gt;warning: Cannot merge binary files: HEAD:somefile.dll vs. otherbranch:somefile.dll

Auto-merging somefile.dll
CONFLICT (content): Merge conflict in somefile.dll
Automatic merge failed; fix conflicts and then commit the result.&lt;/pre&gt;
&lt;p&gt;In this scenario, somefile.dll is a binary file that has been modified in both the current branch, and the branch you are attempting to merge in to the current branch. Since the file cannot be textually merged, you need to make a decision: do you keep the version of the file in your current branch, or the version in the other branch.&lt;/p&gt;
&lt;p&gt;In TortoiseSVN, I was used to being able to right-click on the file in question and choose “Resolve using mine”, or “Resolve using theirs”. So what is the git equivalent?&lt;/p&gt;
&lt;h3&gt;Resolve using mine&lt;/h3&gt;
&lt;p&gt;The file in your working copy is still the copy from your current branch – in other words, it was not modified by the merge attempt. To resolve the conflict and keep this file:&lt;/p&gt;&lt;pre&gt;git add somefile.dll 
git commit –m “My commit message for the merge”&lt;/pre&gt;
&lt;h3&gt;Resolve using theirs&lt;/h3&gt;
&lt;p&gt;If you prefer to resolve the conflict using their copy, you need to get the version of the file from the branch you were trying to merge in:&lt;/p&gt;&lt;pre&gt;git checkout otherbranch somefile.dll&lt;/pre&gt;
&lt;p&gt;Now that you have the correct version of the file in your working copy, you can mark it as resolved (by adding it), and commit:&lt;/p&gt;&lt;pre&gt;git add somefile.dll
git commit –m “My commit message for the merge”&lt;/pre&gt;
&lt;p&gt;Note that in place of &lt;em&gt;otherbranch&lt;/em&gt;, you can use any name (&lt;a href="http://book.git-scm.com/4_git_treeishes.html" target="_blank"&gt;treeish&lt;/a&gt;) that refers to a branch: a local branch name (otherbranch), a remote branch name (origin/master), a specific commit SHA (980e3cc), etc. For example, if you were merging in from your remote when you received the conflict, and you wanted to resolve using the remote version, you would retrieve that copy of the file using:&lt;/p&gt;&lt;pre&gt;git checkout origin/master somefile.dll&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;You then add the file and commit as described above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: There is a shortcut for getting the copy from the other branch (and it even uses the terminology I was expecting):&lt;/p&gt;&lt;pre&gt;git checkout --theirs -- somefile.dll&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=How+to+resolve+a+binary+file+conflict+with+Git&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f01%2f28%2fhow-to-resolve-a-binary-file-conflict-with-git.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f01%2f28%2fhow-to-resolve-a-binary-file-conflict-with-git.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=53018" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=uWIxK1oRfjg:4oELuYT5ur4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/uWIxK1oRfjg" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/git/default.aspx">git</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/01/28/how-to-resolve-a-binary-file-conflict-with-git.aspx</feedburner:origLink></item><item><title>FubuMVC – Define your actions your way</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/ltHZrJaCyx4/fubumvc-define-your-actions-your-way.aspx</link><pubDate>Mon, 18 Jan 2010 19:41:14 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:49186</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>11</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=49186</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/01/18/fubumvc-define-your-actions-your-way.aspx#comments</comments><description>&lt;p&gt;In this post I’m going to try and demonstrate the flexibility that &lt;a href="http://fubumvc.com/" target="_blank"&gt;FubuMVC&lt;/a&gt; allows in how you build your web applications. While FubuMVC is opinionated about some things (lean on your container as much as possible), it mostly gets out of your way to let you work the way you want. We know how valuable it can be to work with an opinionated framework that allows you to move quickly as long as you follow its conventions, but we also know how painful it can be when you find yourself fighting established conventions at every step. With FubuMVC, &lt;em&gt;you&lt;/em&gt; define the conventions and build your own opinionated framework, on top of which you build your applications. But don’t let the sound of building your own framework scare you off, as I’m going to demonstrate how little effort that requires.&lt;/p&gt;  &lt;h2&gt;The sample application&lt;/h2&gt;  &lt;p&gt;I’ve built a very simple application that will help me illustrate the process. The application allows the user to make a list of movies they want to see.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/mymovies_5F00_5CD96F57.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="mymovies" border="0" alt="mymovies" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/mymovies_5F00_thumb_5F00_5645EFC7.png" width="484" height="354" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There are three actions that the application handles:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;strong&gt;Url (route)&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;/movies/list&lt;/td&gt;        &lt;td valign="top" width="200"&gt;show the list of movies&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;/movies/add&lt;/td&gt;        &lt;td valign="top" width="200"&gt;add a movie to the list&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;/movies/remove&lt;/td&gt;        &lt;td valign="top" width="200"&gt;remove a movie from the list&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;I built three different implementations of the same application. All of the code is available in the &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/tree/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions" target="_blank"&gt;src/Actions&lt;/a&gt; folder of the &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples" target="_blank"&gt;fubumvc-examples&lt;/a&gt; repository.&lt;/p&gt;  &lt;h2&gt;Controller/Action&lt;/h2&gt;  &lt;p&gt;The first version of the application (&lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/tree/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/ControllerActionStyle" target="_blank"&gt;ControllerActionStyle&lt;/a&gt;) uses the familiar “controller/action” approach, where multiple actions are defined on a single controller. The first part of the route identifies the controller class, and the second part is the name of a method to call on that class. This convention is fairly easy to declare, since FubuMVC already does a lot of it by default.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Sidebar: Your conventions are declared by defining a class that derives from FubuRegistry and then passing it to a FubuBootstrapper (like FubuStructureMapBootstrapper) at application startup. FubuRegistry exposes a DSL for you to use to describe things like: how to identify methods that should be treated as actions, what the routes for those actions should be, how to decide the output for those actions, and if the output is rendered from a view, which view should it use.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The relevant parts in our &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/ControllerActionStyle/SimpleWebsite/SimpleWebsiteFubuRegistry.cs" target="_blank"&gt;registry&lt;/a&gt; are:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:50a6eb6f-1ea8-4f8d-bb10-ea78939b05f0" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:firstline[15]"&gt;Actions.IncludeTypesNamed(x =&amp;gt; x.EndsWith("Controller"));

Routes.IgnoreControllerNamespaceEntirely();&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This tells FubuMVC to look at all available types whose name ends with the word “Controller”. By default, all public methods (with, at most, 1 input parameter) are treated as actions, so nothing further needs to be specified. It also tells FubuMVC to ignore the namespace on controller classes when building routes. By default, routes are defined as parts/of/namespace/classname/methodname (and the “controller” suffix of the classname is removed by default). By stating we want to ignore the namespace, our routes will look like classname/methodname.&lt;/p&gt;

&lt;p&gt;Following this convention, I built a &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/ControllerActionStyle/SimpleWebsite/Controllers/MoviesController.cs" target="_blank"&gt;MoviesController&lt;/a&gt; class which contains methods for List(), Add(), and Remove().&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a13af1b3-f18d-41b9-af6f-1c6dda3458c2" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class MoviesController
{
    public ListMoviesViewModel List()
    {
		//
    }

    public AjaxResponse Add(AddMovieInput model)
    {
		//
    }

    public AjaxResponse Remove(RemoveMovieInput model)
    {
		//
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;To verify that everything is configured correctly, I open my browser to http://localhost/myapp/_fubu/ to view the list of routes and what actions they will call:&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Route&lt;/th&gt;

      &lt;th&gt;Action(s)&lt;/th&gt;

      &lt;th&gt;Output(s)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;movies/add&lt;/td&gt;

      &lt;td&gt;MoviesController.Add()&lt;/td&gt;

      &lt;td&gt;Json&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;movies/list&lt;/td&gt;

      &lt;td&gt;MoviesController.List()&lt;/td&gt;

      &lt;td&gt;WebForm View '~/Controllers/List.aspx'&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;movies/remove&lt;/td&gt;

      &lt;td&gt;MoviesController.Remove()&lt;/td&gt;

      &lt;td&gt;Json&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;h2&gt;Controller-less Actions&lt;/h2&gt;

&lt;p&gt;The second version of the application (&lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/tree/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/HandlerStyle" target="_blank"&gt;HandlerStyle&lt;/a&gt;) defines each action within its own handler class. This is sometimes referred to as the “controller-less action” approach. I started with the code from the ControllerActionStyle and pulled all of the actions out of MoviesController into their own classes ListHandler, AddHandler, and RemoveHandler in a Movies subfolder. They all have a single public method named “Execute” which does all of the work for that action. You might think that with such a drastic change in how actions are organized that I would need to write a lot of code to wire everything up again. But since I’m still following a convention, I just need to describe it to FubuMVC in my &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/HandlerStyle/SimpleWebsite/SimpleWebsiteFubuRegistry.cs" target="_blank"&gt;registry&lt;/a&gt;:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e3523791-aec2-4bc4-b00d-b8216d519c51" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:firstline[16]"&gt;Actions
    .IncludeTypes(t =&amp;gt; t.Namespace.StartsWith(typeof(HandlerUrlPolicy).Namespace) &amp;amp;&amp;amp; t.Name.EndsWith("Handler"))
    .IncludeMethods(action =&amp;gt; action.Method.Name == "Execute");

Routes.UrlPolicy&amp;lt;HandlerUrlPolicy&amp;gt;();&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This states that actions are located by looking for public methods named “Execute” on types in the Handlers namespace whose name ends with “Handler”. Since my routes no longer follow the usual classname/methodname pattern, I defined a custom URL policy in &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/HandlerStyle/SimpleWebsite/Handlers/HandlerUrlPolicy.cs" target="_blank"&gt;HandlerUrlPolicy&lt;/a&gt;:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c6efa6df-ebfe-4524-93b1-3e6cf48c31e4" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:firstline[7]"&gt;public class HandlerUrlPolicy : IUrlPolicy {
    public bool Matches(ActionCall call)
    {
        return call.HandlerType.Name.EndsWith("Handler");
    }

    public IRouteDefinition Build(ActionCall call)
    {
        var routeDefinition = call.ToRouteDefinition();
        routeDefinition.Append(call.HandlerType.Namespace.Replace(GetType().Namespace + ".", string.Empty).ToLower());
        routeDefinition.Append(call.HandlerType.Name.Replace("Handler", string.Empty).ToLower());
        return routeDefinition;
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Matches method states that this policy only applies to actions whose type name ends with “Handler”. This allows us to have different URL conventions for different parts of an application. The Build method is where we state what the route should look like for each action.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Side note: If you are coming from ASP.NET MVC, you may have picked up on a difference in how routes are defined. With ASP.NET MVC, you define route patterns at application startup (ex: {controller}/{action}), and then as a request comes in, a route pattern is matched, and the MvcRouteHandler object uses the parameter values to try and locate an action (which may not exist). In FubuMVC, each route has its own IRouteHandler in the container which is tied directly its action up front. Every addressable action has an entry in the route table, so if a route is matched, we know exactly which action to execute. FubuMVC routes can still have parameters, but they are only used to provides inputs to the action – not to determine the action.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We build the first part of the route by taking the namespace of our action types (SimpleWebsite.Handlers.Movies) and chopping off the beginning part (SimpleWebsite.Handlers), which is the namespace of the HandlerUrlPolicy. The second part of the route is determined by taking the name of the type where the action is defined and chopping off the “Handler” suffix. Now when we browse to _fubu we see that our routes are still the same as they were in the ControllerActionStyle, but they map to our new actions:&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Route&lt;/th&gt;

      &lt;th&gt;Action(s)&lt;/th&gt;

      &lt;th&gt;Output(s)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;movies/add&lt;/td&gt;

      &lt;td&gt;AddHandler.Execute()&lt;/td&gt;

      &lt;td&gt;Json&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;movies/list&lt;/td&gt;

      &lt;td&gt;ListHandler.Execute()&lt;/td&gt;

      &lt;td&gt;WebForm View '~/Handlers/Movies/List.aspx'&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;movies/remove&lt;/td&gt;

      &lt;td&gt;RemoveHandler.Execute()&lt;/td&gt;

      &lt;td&gt;Json&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;h2&gt;REST-like&lt;/h2&gt;

&lt;p&gt;The final version of the application (&lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/tree/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/EndPointStyle" target="_blank"&gt;EndPointStyle&lt;/a&gt;) defines each action in a REST&lt;em&gt;ish&lt;/em&gt; manner (I’m not brave enough to claim REST&lt;em&gt;ful&lt;/em&gt;). It is similar to the HandlerStyle approach in that each route is handled by a single class, but instead of a single “Execute” method, there is a method for each HTTP method (GET, POST, etc) that is valid for the endpoint. Once again, the convention is defined in our &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/EndPointStyle/SimpleWebsite/SimpleWebsiteFubuRegistry.cs" target="_blank"&gt;registry&lt;/a&gt;:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9174917a-dfeb-4c41-be6c-e1d176131fa3" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:firstline[17]"&gt;var httpVerbs = new HashSet&amp;lt;string&amp;gt;(StringComparer.InvariantCultureIgnoreCase)
    {"GET", "POST", "PUT", "HEAD"};

Actions
    .IncludeTypes(t =&amp;gt; t.Namespace.StartsWith(typeof(EndPointUrlPolicy).Namespace) &amp;amp;&amp;amp; t.Name.EndsWith("Endpoint"))
    .IncludeMethods(action =&amp;gt; httpVerbs.Contains(action.Method.Name));

httpVerbs.Each(verb =&amp;gt; Routes.ConstrainToHttpMethod(action =&amp;gt; action.Method.Name.Equals(verb, StringComparison.InvariantCultureIgnoreCase), verb));

Routes.UrlPolicy&amp;lt;EndPointUrlPolicy&amp;gt;();&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Actions are located by searching all types with the “Endpoint” suffix in the Endpoint namespace for methods named after an HTTP method. Routes are constructed in a custom URL policy (&lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/EndPointStyle/SimpleWebsite/EndPoints/EndPointUrlPolicy.cs" target="_blank"&gt;EndPointUrlPolicy&lt;/a&gt;) that has the same logic we used in the HandlerStyle example (namespace/classnamewithoutsuffix). In line 24, I add a policy that constrains the acceptable HTTP method for a route based on the name of the class method that handles it (ex: the Get() method should only respond to HTTP GETs). This enables us to tie the same route pattern to multiple actions, based on how the request is made.&lt;/p&gt;

&lt;p&gt;To demonstrate this functionality, I added a new feature to the sample application: the ability to sort your movies in your order of preference, and have the system remember that order. When the movies are sorted (using the very cool &lt;a href="http://www.jqueryui.com/demos/sortable/" target="_blank"&gt;jQuery sortable&lt;/a&gt;), a message is posted to movies/list endpoint with the new order. The Post() method on the &lt;a href="http://github.com/DarthFubuMVC/fubumvc-examples/blob/db3770dfe028e09f10a0867a33b361130f590b0d/src/Actions/EndPointStyle/SimpleWebsite/EndPoints/Movies/ListEndpoint.cs" target="_blank"&gt;ListEndpoint&lt;/a&gt; is invoked to save the order in the repository, as opposed to the Get() method on ListEndpoint which displays the current list of movies.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:dc702d01-b02c-4069-9380-8710e853348e" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class ListEndpoint
{
    public ListMoviesViewModel Get()
    {
		// show the current list of movies
    }

    public AjaxResponse Post(UpdateMovieListOrder input)
    {
		// save the order in which the movies should be displayed
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Another visit to the _fubu diagnostics page confirms the routes are wired up as we intended (note that movies/list shows up twice, with 2 different actions):&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Route&lt;/th&gt;

      &lt;th&gt;Action(s)&lt;/th&gt;

      &lt;th&gt;Output(s)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;[POST] movies/add&lt;/td&gt;

      &lt;td&gt;AddEndpoint.Post()&lt;/td&gt;

      &lt;td&gt;Json&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;[GET] movies/list&lt;/td&gt;

      &lt;td&gt;ListEndpoint.Get()&lt;/td&gt;

      &lt;td&gt;WebForm View '~/EndPoints/Movies/List.aspx'&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;[POST] movies/list&lt;/td&gt;

      &lt;td&gt;ListEndpoint.Post()&lt;/td&gt;

      &lt;td&gt;Json&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;[POST] movies/remove&lt;/td&gt;

      &lt;td&gt;RemoveEndpoint.Post()&lt;/td&gt;

      &lt;td&gt;Json&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;h3&gt;Wrap Up&lt;/h3&gt;

&lt;p&gt;If you compare the three implementations of the movie application, you will notice that very little had to change as far as FubuMVC is concerned. By changing a couple lines in my FubuRegistry and creating a custom IUrlPolicy with 5 lines of logic, I was able to establish conventions to let me build my application in my preferred style (controllers, handlers, or endpoints). Other .NET web frameworks may have the extension points to allow each of these styles, but I’d be willing to bet you would have to write a lot more custom code and possibly have to give up some of the out of the box functionality the framework provides (if you prove me wrong, leave a comment and I’ll update the post to link to your example).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=FubuMVC+%e2%80%93+Define+your+actions+your+way&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f01%2f18%2ffubumvc-define-your-actions-your-way.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2010%2f01%2f18%2ffubumvc-define-your-actions-your-way.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=49186" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=ltHZrJaCyx4:18ioMtRL2VA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/ltHZrJaCyx4" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/fubumvc/default.aspx">fubumvc</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/01/18/fubumvc-define-your-actions-your-way.aspx</feedburner:origLink></item><item><title>Readable Regular Expressions Revisited</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/MB7WIH-4HNE/readable-regular-expressions-revisited.aspx</link><pubDate>Sat, 19 Dec 2009 16:24:47 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:40136</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=40136</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/12/19/readable-regular-expressions-revisited.aspx#comments</comments><description>&lt;p&gt;Many, many years ago (internet time), I proposed a &lt;a href="http://flimflan.com/blog/ReadableRegularExpressions.aspx" target="_blank"&gt;fluent interface for composing regular expressions&lt;/a&gt;. People either loved the idea or hated it (or thought it was just ok). The intention was to try and tackle the opaqueness of regular expressions that might be embedded in your otherwise familiar C# source code.&lt;/p&gt;  &lt;p&gt;I’ll confess I never used that approach in production code. It started as a thought experiment, and that’s as far as it went (for me, at least). However, I did pick up a great technique from the comments. &lt;a href="http://www.omegacoder.com/" target="_blank"&gt;William “OmegaMan” Wegerson&lt;/a&gt; suggested using RegexOptions.IgnorePatternWhitespace along with liberal usage of in-line comments. Here is a recent example from the &lt;a href="http://code.google.com/p/fubumvc/" target="_blank"&gt;fubumvc&lt;/a&gt; source:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c59d66d8-076f-4af1-937e-27b45bccdf5e" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:nocontrols"&gt;const string propertyFindingPattern = @"
\{              # start variable
(?&amp;lt;varname&amp;gt;\w+) # capture 1 or more word characters as the variable name
(:              # optional section beginning with a colon
(?&amp;lt;default&amp;gt;\w+) # capture 1 or more word characters as the default value
)?              # end optional section
\}              # end variable"; 
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice that the comments violate one of the main rules of good commenting: do not restate what the code says. Usually, someone reading your code is literate enough in the programming language that they can figure out “what” the code does, it just isn’t always clear “why”. But when it comes to regular expressions, I would guess that a majority of C# programmers need to look at a regex reference every time they try and decipher a pattern. Do them a favor and document what each part of the pattern does while you are writing it, since you’re probably looking at the reference already anyway. This should make it much easier for someone to follow (and modify) the code going forward. No fancy fluent interface required.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Readable+Regular+Expressions+Revisited&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f12%2f19%2freadable-regular-expressions-revisited.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f12%2f19%2freadable-regular-expressions-revisited.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=40136" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=MB7WIH-4HNE:idVKa2IdwzM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/MB7WIH-4HNE" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/12/19/readable-regular-expressions-revisited.aspx</feedburner:origLink></item><item><title>Big Visible TeamCity</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/Bqq6A1LNgRA/big-visible-teamcity.aspx</link><pubDate>Fri, 28 Aug 2009 20:00:34 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:24285</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>15</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=24285</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/08/28/big-visible-teamcity.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://code.google.com/p/bigvisiblecruise/" target="_blank"&gt;Big Visible Cruise&lt;/a&gt; is a cool utility for adding a build information radiator to your team room. It makes your Cruise Control build status immediately clear with a large green (good) or red (bad) screen. My (admittedly limited) search for an equivalent solution for &lt;a href="http://www.jetbrains.com/teamcity/" target="_blank"&gt;JetBrains’ TeamCity&lt;/a&gt; came up empty. TeamCity has a few built-in notification options, but none of them seemed to be the right fit. I toyed with many different possibilities, all of which would require more development or infrastructure than we wanted to allocate to the task. Luckily, we found a solution that cost us little time and requires very little deployment footprint.&lt;/p&gt;  &lt;p&gt;On individual build configuration pages, there is an option to “enable status widget”. This makes the build status publicly available on your TeamCity server at http://&amp;lt;buildserver&amp;gt;/externalStatus.html. This is what it looks like when we expose the status of our two builds:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_1F29D679.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_thumb_5F00_5E1B5714.png" width="644" height="498" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, we can put that up on a big monitor for everyone to see, but I don’t think it “radiates” any information – you still need to purposefully read it. However, through the power of &lt;a href="http://www.greasespot.net/" target="_blank"&gt;GreaseMonkey&lt;/a&gt; and &lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt;, we were able to modify that page to look like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_21172582.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_thumb_5F00_6008A61D.png" width="644" height="497" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, it is immediately clear to anyone in the room when one of our builds has a problem. The script also refreshes the page automatically every 15 seconds, which the default externalStatus.html page does not do.&lt;/p&gt;  &lt;p&gt;You can easily recreate this using Firefox, the GreaseMonkey Add-on, and my &lt;a href="http://code.google.com/p/pablo/source/browse/trunk/joshuaflanagan/bigvisibleteamcity/bigvisibleteamcity.user.js" target="_blank"&gt;bigvisibleteamcity.user.js&lt;/a&gt; GreaseMonkey extension. If you aren’t familiar with GreaseMonkey, just install the add-on, then drag the *.user.js file onto your browser window, and you will be prompted to install it.&lt;/p&gt;  &lt;p&gt;You will need to edit the bigvisibleteamcity.user.js file to change the URL in the @include line to refer to the externalStatus.html page on your server.&lt;/p&gt;  &lt;p&gt;I didn’t spend a lot of time on the styling, but the hooks are there if you want to. If you are familiar with javascript, it should be clear in the source how to change the refresh time, or to add support for multiple rows of boxes, etc. Let me know if you make any cool changes.&lt;/p&gt;  &lt;p&gt;Credit due to Dovetail cohorts &lt;a href="http://www.lostechies.com/blogs/chad_myers/" target="_blank"&gt;Chad Myers&lt;/a&gt; for the idea and &lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/" target="_blank"&gt;Sam Tyson&lt;/a&gt; for bootstrapping me on GreaseMonkey scripting.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Big+Visible+TeamCity&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f08%2f28%2fbig-visible-teamcity.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f08%2f28%2fbig-visible-teamcity.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=24285" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=Bqq6A1LNgRA:wjat_g1BXIs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/Bqq6A1LNgRA" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/teamcity/default.aspx">teamcity</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/greasemonkey/default.aspx">greasemonkey</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/08/28/big-visible-teamcity.aspx</feedburner:origLink></item><item><title>How we handle application configuration</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/rgxseYx4rIA/how-we-handle-application-configuration.aspx</link><pubDate>Mon, 13 Jul 2009 00:38:15 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22829</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>23</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=22829</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/07/12/how-we-handle-application-configuration.aspx#comments</comments><description>&lt;p&gt;We recently overhauled the way we handle configurable settings within our application (server names, email addresses, polling frequencies, etc) . I’m going to present our solution below, but its new enough that I’d like to hear feedback on how others approach the problem.&lt;/p&gt;  &lt;h3&gt;The goal&lt;/h3&gt;  &lt;p&gt;We want a configuration solution with the following traits:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;No magic strings&lt;/strong&gt;. The configurable values will ultimately be stored with an identifying string key, but we didn’t want client code to have to know and use that string. The potential for typos is high, and maintaining a parallel list of constants is tedious. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Strongly-typed values&lt;/strong&gt;. The configured values will likely be stored as strings in a configuration file, but we never want client code to know that. If the configurable value is numeric, the consumer should get a number. Forcing the consumer to deal with type conversion (and related error handling) would create a lot of duplicate, error prone, “ceremony” code that would obscure the essence of what it is trying to accomplish.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Test friendly.&lt;/strong&gt; Client code that depends on a configurable value should not be forced to have any “out of process” dependencies (database, file system, etc.). Ideally, we would like to avoid having to stub expectations or use a test fake for configuration. We would also like to avoid adding any “simple type” (int, bool, string) constructor arguments to our classes, since the &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/02/03/auto-mocking-explained.aspx" target="_blank"&gt;automocker&lt;/a&gt; we use cannot handle them. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Tooling friendly.&lt;/strong&gt; We will have a large number of configurable values in many different places around the codebase. Our solution should make it easy to build tooling to generate a sample configuration to document all of the possible settings. We also want to be able to validate an existing configuration to make sure all necessary values have been provided. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Though not necessary, it would also be nice to have:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Default values.&lt;/strong&gt; Users should only have to configure the values that have no sensible default, or values they want to override. It should not be left up to the client code to handle checking for a configured value, or falling back to a hardcoded default. That’s more “ceremony” code, not to mention the fact that multiple clients that use the same configurable settings would all have to know the default. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;App.config/web.config&lt;/strong&gt; Storing application configuration settings in an app.config or web.config is a well-established convention in the .NET world. It already has support for encryption, multiple file overrides, and tooling. We should use it if it doesn’t cause too much pain. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Our solution in action&lt;/h3&gt;  &lt;p&gt;To explain our solution, I’ll use the example of a service that associates an uploaded image with a user profile. Users might upload images of all sizes, and in many different formats, but we want to make sure they are all stored in the same size and format. We want to give owner’s of our application the ability to set the standard size and format, so they must be configurable. We also want to make sure the path where images are stored is configurable. Consider the following implementation:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:357f757b-0aee-4ef1-a827-69cc904e3b6c" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class AvatarService : IAvatarService
{
    private readonly AvatarSettings _settings;
    private readonly IFileSystem _fileSystem;
    private readonly IImageService _imageService;

    public AvatarService(AvatarSettings settings, IFileSystem fileSystem, IImageService imageService)
    {
        _settings = settings;
        _fileSystem = fileSystem;
        _imageService = imageService;
    }

    public void SaveAvatar(User user, Stream originalImage)
    {
        var extension = _imageService.GetImageExtensionFromMimeType(_settings.PreferredMimeType);
        var pathToSave = Path.Combine(_settings.AvatarStoragePath, user.Id + extension);
        user.AvatarFilePath = pathToSave;
        var scaledImage = _imageService.ScaleImageWithCrop(originalImage,
            _settings.PreferredMimeType,
            _settings.DefaultWidth,
            _settings.DefaultHeight);
        _fileSystem.Write(scaledImage, pathToSave);
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, in order for the class to make use of these externally configured values, it just needs to take an instance of AvatarSettings in its constructor. At runtime, the settings will be injected by our composition tool (&lt;a href="http://structuremap.sourceforge.net" target="_blank"&gt;StructureMap&lt;/a&gt;), just like the file system and image services. The AvatarSettings itself is a simple &lt;a href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object" target="_blank"&gt;POCO&lt;/a&gt; class:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:591afbeb-4ae5-484d-9450-f317f0850081" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class AvatarSettings : DictionaryConvertible
{
    public AvatarSettings()
    {
        PreferredMimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
        DefaultWidth = DefaultHeight = 64;
    }

    [ExpandEnvironmentVariables]
    public string AvatarStoragePath { get; set; }
    public int DefaultWidth { get; set; }
    public int DefaultHeight { get; set; }
    public string PreferredMimeType { get; set; }
}

public abstract class DictionaryConvertible
{
    private readonly List&amp;lt;ConvertProblem&amp;gt; _problems = new List&amp;lt;ConvertProblem&amp;gt;();
    public IEnumerable&amp;lt;ConvertProblem&amp;gt; Problems { get { return _problems; } }

    public void AddProblem(ConvertProblem problem)
    {
        _problems.Add(problem);
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I’ll discuss the DictionaryConvertible base class later, but I included it here to show that it does not bring along any extra baggage that would hinder the testability of derived classes. When testing client code like the AvatarService, we can prepare a specific test context by setting configuration values directly on an AvatarSettings instance. This is more natural than stubbing values on a fake. If we are testing a scenario that is not impacted by the configuration values, we can just let the automocker pass in a default instance. &lt;/p&gt;

&lt;p&gt;To set the configurable values for the application, we just need to add corresponding keys to the appSettings section of the app.config/web.config file:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c7ef3148-552a-4f08-99c5-1d794ca5959c" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;appSettings&amp;gt;
  &amp;lt;add key=&amp;quot;AvatarSettings.AvatarStoragePath&amp;quot; value=&amp;quot;%ALLUSERSPROFILE%\DovetailCRM\Avatars&amp;quot;/&amp;gt;
  &amp;lt;add key=&amp;quot;AvatarSettings.DefaultWidth&amp;quot; value=&amp;quot;96&amp;quot;/&amp;gt;
  &amp;lt;add key=&amp;quot;AvatarSettings.DefaultHeight&amp;quot; value=&amp;quot;96&amp;quot;/&amp;gt;
&amp;lt;/appSettings&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are a few things worth noting here. First, I have not included a value for AvatarSettings.PreferredMimeType in the config file. If you look at the source for AvatarSettings, you’ll notice it is set in the constructor. That is how we declare default values. It allows us to avoid cluttering up the config file with a bunch of settings that have reasonable defaults, while still allowing the flexibility to override them if desired. This is illustrated by the DefaultWidth and DefaultHeight settings which have configured values that override the defaults from the constructor. Also notice that the DefaultWidth and DefaultHeight properties are declared as integers (even though the values are strings in the config file) so that client code does not have to do any type conversion. &lt;/p&gt;

&lt;p&gt;The final thing to notice is the [ExpandEnvironmentVariables] attribute that decorates the AvatarStoragePath property. In addition to type conversion, the code that populates a settings object can use additional metadata to do further manipulation of the configured values. In this case, the value “%ALLUSERSPROFILE%\DovetailCRM\Avatars” will be converted to “c:\ProgramData\DovetailCRM\Avatars” before any client code ever sees it. This not only simplifies the client code, but eliminates duplication of logic when a settings object has more than one client.&lt;/p&gt;

&lt;h3&gt;How it works&lt;/h3&gt;

&lt;p&gt;So how does this all work? The Settings object needs to be populated from the configuration file, so we define an interface for this responsibility:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:4ae91875-233b-40a2-828f-1f4c32de4a2b" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public interface ISettingsProvider
{
    DictionaryConvertible PopulateSettings(DictionaryConvertible instance);
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Implementations take in an instance of a DictionaryConvertible derived type, and should return an instance of the same type with all of the settings populated. We have a single implementation, AppSettingsProvider, which gets values from the &amp;lt;appSettings/&amp;gt; section of the app.config/web.config. Under the hood it makes use of a class that knows how to cycle over the properties of an object and set them using values from a dictionary (very similar to the &lt;a href="http://github.com/chadmyers/FubuMVC/blob/58f9aaaa098ca0d652b2c9c2c22f6de5626998e2/src/FubuMVC.Core/Controller/DictionaryConverter.cs" target="_blank"&gt;DictionaryConverter&lt;/a&gt; in fubumvc). Any problems encountered during the conversion are recorded using the AddProblem method of the DictionaryConvertible, hence the original reason for the base class. We were already using this code to populate the input models for our MVC controller actions (similar to the ModelBinders that were introduced in ASP.NET MVC), so it made sense to re-use it.&lt;/p&gt;

&lt;p&gt;The final step is to tell StructureMap how to create instances of the settings classes so that they are properly injected into consumers. In our &lt;a href="http://structuremap.sourceforge.net/RegistryDSL.htm" target="_blank"&gt;Registry&lt;/a&gt;, we add:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:db67afdd-65fc-4d7a-9af0-b2b871cd5e15" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;For&amp;lt;AvatarSettings&amp;gt;()
  .Use&amp;lt;AvatarSettings&amp;gt;()
  .EnrichWith((session, original) =&amp;gt; 
      session.GetInstance&amp;lt;ISettingsProvider&amp;gt;().PopulateSettings(original));
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is a good example of making use of the advanced power of your composition tool (and a good argument against trying to make a &lt;a href="http://www.codeplex.com/CommonServiceLocator" target="_blank"&gt;Common Service Locator&lt;/a&gt; equivalent for service registration). We use the &lt;a href="http://structuremap.sourceforge.net/Interception.htm#section3" target="_blank"&gt;EnrichWith&lt;/a&gt; statement to tell StructureMap “when I ask you for an AvatarSettings instance, before returning it to me, you should first pass it through the PopulateSettings method of my configured ISettingsProvider.”&lt;/p&gt;

&lt;p&gt;Of course, it wasn’t long before we started adding a number of these Settings classes to our codebase, and it became a tedious extra step to add this same registration code for each class. The next logical step was to create a &lt;a href="http://structuremap.sourceforge.net/ScanningAssemblies.htm#section11" target="_blank"&gt;custom type scanner&lt;/a&gt;:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:4e5eabe3-79e7-41db-9484-4b275ccba7cc" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class SettingsScanner : ITypeScanner
{
    public void Process(Type type, PluginGraph graph)
    {
        if (!type.Name.EndsWith(&amp;quot;Settings&amp;quot;) || !typeof (DictionaryConvertible).IsAssignableFrom(type)) return;
        graph.Configure(r =&amp;gt; r.For(type).EnrichWith((session, original) =&amp;gt;
        {
            return session.GetInstance&amp;lt;ISettingsProvider&amp;gt;().PopulateSettings((DictionaryConvertible)original);
        }).TheDefaultIsConcreteType(type));
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We could now remove the previous code from our Registry that registered a single class (AvatarSettings), and replace it with this code which has the same effect for ALL Settings classes in our codebase:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:27b6d571-24b1-4df4-9bf0-48fa31871904" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;Scan(x =&amp;gt;
{
    x.TheCallingAssembly();
    x.With&amp;lt;SettingsScanner&amp;gt;();
});&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;Tooling support&lt;/h3&gt;

&lt;p&gt;One of our goals was that the configurable settings should be easy to document. With a growing number of Settings classes all over the codebase, it could be very easy to lose track of which values are needed in the configuration file. However, since all of the Settings class follow a convention (derive from DictionaryConvertible, and named with the “Settings” suffix), it is trivial to write a little utility to reflect over the code and write out a sample &amp;lt;appSettings /&amp;gt; section.&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:ef6dc01b-b7cc-4096-a0e7-7cc4de666013" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#:collapse"&gt;public void Execute(string[] args)
{
    var settingTypes = _container.Model.PluginTypes
        .Where(t =&amp;gt; t.PluginType.Name.EndsWith(&amp;quot;Settings&amp;quot;) &amp;amp;&amp;amp; t.PluginType.BaseType == typeof(DictionaryConvertible))
        .Select(t =&amp;gt; t.PluginType);

    dumpSettings(settingTypes, Console.Out);
    Console.WriteLine();
}

private void dumpSettings(IEnumerable&amp;lt;Type&amp;gt; settingTypes, TextWriter output)
{
    var xml = new XmlTextWriter(output) {Formatting = Formatting.Indented};
    xml.WriteStartElement(&amp;quot;appSettings&amp;quot;);
    settingTypes.Each(t =&amp;gt;
    {
        var settings = Activator.CreateInstance(t);
        var properties = t.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);

        properties.Each(p =&amp;gt;
        {
            var key = AppSettingsProvider.DefaultNamingStrategy(p);
            var value = p.GetValue(settings, null);

            xml.WriteStartElement(&amp;quot;add&amp;quot;);
            xml.WriteAttributeString(&amp;quot;key&amp;quot;, key);
            xml.WriteAttributeString(&amp;quot;value&amp;quot;, value == null ? &amp;quot;&amp;quot; : value.ToString());
            xml.WriteEndElement();
        });
    });
    xml.WriteEndElement();
    xml.Close();
}&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;All of this comes together to allow a very natural workflow when we decide we need to make a value in our code configurable:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a new Settings class (or append to an existing class) that derives from DictionaryConvertible&amp;#160; and add the properties for each of the configurable values we need. Optionally initialize the properties with a default value in the constructor. &lt;/li&gt;

  &lt;li&gt;Add the Settings class as a constructor parameter in the client class that needs the configurable value. &lt;/li&gt;

  &lt;li&gt;After the client class is done and tested, add an &amp;lt;appSettings /&amp;gt; entry to the application configuration file for each setting without a default value. &lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=How+we+handle+application+configuration&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f07%2f12%2fhow-we-handle-application-configuration.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f07%2f12%2fhow-we-handle-application-configuration.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22829" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=rgxseYx4rIA:quE5TPHsqwE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/rgxseYx4rIA" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/structuremap/default.aspx">structuremap</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/infrastructure/default.aspx">infrastructure</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/07/12/how-we-handle-application-configuration.aspx</feedburner:origLink></item><item><title>Real World Refactoring</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/WiQJ5sbwOfE/real-world-refactoring.aspx</link><pubDate>Mon, 29 Jun 2009 00:35:29 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22485</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=22485</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/06/28/real-world-refactoring.aspx#comments</comments><description>&lt;p&gt;If you’ve ever asked, or been asked, for an example to illustrate a software design principle, you know how frustrating it can be to work with a contrived example. There is rarely any depth to the example, and it lines up so neatly with the concept being explained that the student may have trouble recognizing similar situations in the wild. I’m going to try and relate a real world example of a recent refactoring effort, with the hope that the extra context and narrated walkthrough will help someone make a connection that has failed before.&lt;/p&gt;  &lt;h3&gt;A little background&lt;/h3&gt;  &lt;p&gt;My discussion revolves around &lt;a href="http://docu.jagregory.com/" target="_blank"&gt;Docu&lt;/a&gt;, which is an open source project for converting .NET XML comments into HTML documentation. (&lt;em&gt;Note: I want to make clear is that this is not a criticism of any of the Docu code. All code is written with specific goals and constraints in mind. As the goals evolve, some designs that worked perfectly in early iterations may start to create friction, and deserve to be reconsidered.&lt;/em&gt;) &lt;a href="http://msdn.microsoft.com/en-us/library/b2s063f7.aspx" target="_blank"&gt;.NET XML comments&lt;/a&gt; are constructed by applying a set of top-level tags to code elements such as classes, methods, or properties. Top-level tags are things like &lt;a href="http://msdn.microsoft.com/en-us/library/2d6dt3kf.aspx" target="_blank"&gt;&amp;lt;summary/&amp;gt;&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/3zw4z1ys.aspx" target="_blank"&gt;&amp;lt;remarks/&amp;gt;&lt;/a&gt;, or &lt;a href="http://msdn.microsoft.com/en-us/library/8cw818w8.aspx" target="_blank"&gt;&amp;lt;param/&amp;gt;&lt;/a&gt;. Within the contents of the top-level tags, you can use embedded tags to provide additional contextual information. Embedded tags are things like &lt;a href="http://msdn.microsoft.com/en-us/library/acd0tfbe.aspx" target="_blank"&gt;&amp;lt;see/&amp;gt;&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/x640hcd2.aspx" target="_blank"&gt;&amp;lt;para/&amp;gt;&lt;/a&gt;, or &lt;a href="http://msdn.microsoft.com/en-us/library/wb7x2fhw.aspx" target="_blank"&gt;&amp;lt;paramref/&amp;gt;&lt;/a&gt;. The following example shows a top level &amp;lt;remarks/&amp;gt; tag, with embedded &amp;lt;paramref/&amp;gt; and &amp;lt;para/&amp;gt; tags: &lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d9db1802-6276-4d14-b945-b305ebd1578e" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml:nocontrols"&gt;///&amp;lt;remarks&amp;gt;Make sure the &amp;lt;paramref name=”maxValue” /&amp;gt; is a positive number.
///&amp;lt;para&amp;gt;Do not call more than once.&amp;lt;/para&amp;gt;&amp;lt;/remarks&amp;gt; &lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In Docu, the job of translating the XML contents of a single top-level tag into a semantic model is handled by the CommentParser. Let’s take a look at the &lt;a href="http://github.com/jagregory/docu/blob/e5569e48aea80084f1f8c1abc0c77e9d26906e37/src/Docu.Console/Parsing/Comments/CommentParser.cs" target="_blank"&gt;original implementation&lt;/a&gt;:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8a832f5b-43a7-40fe-8c08-b28fce9e9c96" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class CommentParser : ICommentParser
{
    private readonly IDictionary&amp;lt;Func&amp;lt;XmlNode, bool&amp;gt;, Func&amp;lt;XmlNode, bool, bool, IComment&amp;gt;&amp;gt; parsers =
        new Dictionary&amp;lt;Func&amp;lt;XmlNode, bool&amp;gt;, Func&amp;lt;XmlNode, bool, bool, IComment&amp;gt;&amp;gt;();

    private readonly InlineTextCommentParser InlineText = new InlineTextCommentParser();
    private readonly InlineCodeCommentParser InlineCode = new InlineCodeCommentParser();
    private readonly MultilineCodeCommentParser MultilineCode = new MultilineCodeCommentParser();
    private readonly SeeCodeCommentParser See = new SeeCodeCommentParser();
    private readonly ParagraphCommentParser Paragraph;
    private readonly ParameterReferenceParser ParameterReference = new ParameterReferenceParser();
    private readonly InlineListCommentParser InlineList;

    public CommentParser()
    {
        Paragraph = new ParagraphCommentParser(this);
        InlineList = new InlineListCommentParser(this);
        parsers.Add(node =&amp;gt; node is XmlText, InlineText.Parse);
        parsers.Add(node =&amp;gt; node.Name == &amp;quot;c&amp;quot;, InlineCode.Parse);
        parsers.Add(node =&amp;gt; node.Name == &amp;quot;code&amp;quot;, MultilineCode.Parse);
        parsers.Add(node =&amp;gt; node.Name == &amp;quot;see&amp;quot;, See.Parse);
        parsers.Add(node =&amp;gt; node.Name == &amp;quot;para&amp;quot;, Paragraph.Parse);
        parsers.Add(node =&amp;gt; node.Name == &amp;quot;paramref&amp;quot;, ParameterReference.Parse);
        parsers.Add(node =&amp;gt; node.Name == &amp;quot;list&amp;quot;, InlineList.Parse);
    }

    public IList&amp;lt;IComment&amp;gt; Parse(XmlNodeList nodes)
    {
        var blocks = new List&amp;lt;IComment&amp;gt;();

        int count = nodes.Count;
        for(int i = 0; i &amp;lt; count; i++)
        {
            XmlNode node = nodes;
            bool first = (i == 0);
            bool last = (i == (count - 1));

            foreach(var pair in parsers)
            {
                var isValid = pair.Key;
                var parser = pair.Value;

                if(!isValid(node))
                    continue;

                var block = parser(node, first, last);

                if(block != null)
                {
                    blocks.Add(block);
                    continue;
                }
            }
        }

        return blocks;
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see (lines 18-24 above) that in its constructor it builds up a collection of function (Func&amp;lt;&amp;gt;) pairs: one function that is used to identify a specific embedded tag, paired with another function that knows how to parse that tag into its model representation (an instance of IComment). The collection is used by the primary method in CommentParser, which iterates over all of the child nodes of a given chunk of XML, finds a parsing function that can handle that node, invokes the function, and collects the results. &lt;/p&gt;

&lt;p&gt;The functions that perform the parsing of individual embedded tags are implemented in separate classes (I’ll call them “node parsers”). The CommentParser creates an instance of each node parser and stores it in a field where it can be referenced by the collection of function pairs. The benefit of moving the embedded tag parsing into separate classes is that they can be developed and tested independent of CommentParser. Unfortunately, you need to make a number of changes to CommentParser every time you add a new node parser. Since there are still quite a few embedded tags that are not yet recognized by Docu, and each embedded tag (generally) requires a new node parser, the CommentParser class will be continuously modified and unstable. The primary goal of my refactoring effort is to create a more stable CommentParser that is open for extension (support for new embedded tags can be added) but closed for modification. &lt;/p&gt;

&lt;h3&gt;High Cohesion&lt;/h3&gt;

&lt;p&gt;As stated above, the logic for determining when a specific parsing function should be applied was inside of CommentParser, while the logic to implement that function was in the individual parsing classes. These two pieces of logic are tightly related to each other. You cannot safely apply an arbitrary node parser to any node – it only makes sense to apply a parser to the type of node it was designed for. We can make the node parsers and the CommentParser more cohesive by moving both pieces of logic into the node parsing classes. I’ll add a CanParse(XmlNode) method to each node parser. The method returns true if the parser knows how to parse a given comment node. I implement them by copying the logic for identifying specific tags from the Func&amp;lt;&amp;gt; pairs in CommentParser.&lt;/p&gt;

&lt;h3&gt;Low Coupling &lt;/h3&gt;

&lt;p&gt;We still have the problem that the CommentParser creates and stores an instance of each specific node parser class (lines 6-11 above). This high coupling between the CommentParser and the node parsing classes makes it impossible to execute in isolation. You cannot use a CommentParser without bringing all of the functionality of all node parsers along. You also have to modify the CommentParser every time a new type of node parser is added (as when adding support for a new type of comment tag).&lt;/p&gt;

&lt;p&gt;I’ll reduce coupling between CommentParser and individual node parsers by introducing an interface (ICommentNodeParser) to describe the functionality exposed by the node parsers. The CommentParser will only interact with this interface, which exposes the CanParse and Parse methods. I then change the node parsers so that they implement the new interface. Since they already had all of the needed functionality, it was just a matter of making sure the method signatures matched correctly. &lt;/p&gt;

&lt;h3&gt;Slight detour&lt;/h3&gt;

&lt;p&gt;When I started to add the interface to all of the node parsing classes, I noticed they all derived from CommentParserBase. However, none of the code in the application referred to these classes through this base class. That’s a pretty good indicator that inheritance is being used to share common functionality rather than for polymorphism. Using inheritance just to share some common functionality can lead to more inflexible designs and less cohesive classes. You are usually better off using composition instead of inheritance in these scenarios. In this case, the only shared functionality was a single helper method that had some special logic for string trimming. Since the method didn’t make use of any instance data, it was easy to move it to a separate class as an extension method on string. Now that CommentParserBase was empty, there was no reason to keep it around, so it was eliminated. The fact that no code broke when the base class was deleted (without using a refactoring tool) is a good indicator that it was the right decision.&lt;/p&gt;

&lt;h3&gt;Composition through dependency injection&lt;/h3&gt;

&lt;p&gt;At this point we have a bunch of node parsers that all implement a common interface. But the CommentParser is still tightly coupled to the various implementations because it has to create the instances. This is the perfect opportunity to use dependency injection to pass the node parser instances into the CommentParser. I just change the constructor of CommentParser to require an array of ICommentNodeParsers, and delete all the code that was creating the node parser instances. Whoever creates an instance of CommentParser will need to pass in the collection of node parser instances. CommentParser is no longer coupled to the specific node parsers and can be more easily used in isolation. You can see that the newer version is greatly simplified:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:40abf482-65bd-4279-842c-f0dc82396fef" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class CommentParser : ICommentParser
   {
       private readonly ICommentNodeParser[] _parsers;

       public CommentParser(ICommentNodeParser[] parsers)
       {
           _parsers = parsers;
       }

       public IList&amp;lt;IComment&amp;gt; Parse(XmlNodeList nodes)
       {
           var blocks = new List&amp;lt;IComment&amp;gt;();

           var count = nodes.Count;
           for(var i = 0; i &amp;lt; count; i++)
           {
               var node = nodes;
               var first = (i == 0);
               var last = (i == (count - 1));

               var parser = _parsers.FirstOrDefault(p =&amp;gt; p.CanParse(node));
               if (parser == null) continue;

               var block = parser.Parse(this, node, first, last);
               if (block != null)
               {
                   blocks.Add(block);
               }
           }

           return blocks;
       }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At this point you may be thinking I just “passed the buck” for creating the individual node parser instances to another class up the stack. Someone still needs to create them, and will therefore be tightly coupled to the implementations. That is true. However, if we can pass that responsibility up the stack far enough, it can be handled by code that has no other responsibility than to configure and bootstrap our application. That type of code doesn’t typically have any logic that would be re-used and doesn’t have the same concerns about designing for maintainability. Luckily, in the case of Docu, we already use &lt;a href="http://structuremap.sourceforge.net/" target="_blank"&gt;StructureMap&lt;/a&gt; to compose our object instances so we get this functionality for free. I simply had to add a single line to the StructureMap configuration to tell it to make use of any implementation of ICommentNodeParser it finds in the Docu assembly.&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c4eff773-4ded-44d3-831b-39478edb3125" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public DefaultRegistry() {
  Scan(x =&amp;gt;  {
    x.AssemblyContainingType&amp;lt;DocumentationGenerator&amp;gt;();
    x.WithDefaultConventions();
    x.AddAllTypesOf&amp;lt;ICommentNodeParser&amp;gt;();&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now when an instance of CommentParser is requested from StructureMap, it will automatically have the array of all node parsers injected to its constructor.&lt;/p&gt;

&lt;h3&gt;Wrap up&lt;/h3&gt;

&lt;p&gt;So what did we gain? Let’s compare the stories for adding the ability to parse a new XML documentation tag. In the original implementation, we had to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a class with code that parses the new tag &lt;/li&gt;

  &lt;li&gt;Create a new field in CommentParser to hold an instance of the new parsing class &lt;/li&gt;

  &lt;li&gt;Modify CommentParser’s constructor to register the new class, along with a predicate that determines when it should be used &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And now we simply:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a class that implements ICommentNodeParser with code that recognizes and parses the new tag &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notice that you didn’t have to touch CommentParser? We just gave it new functionality without having to change (and potentially destabilize) the code. That’s the open-closed principle in action. The increased cohesion of the node parsers makes them easier to understand and helps localize any future changes to their implementation. We also saw that the use of dependency injection and a composition tool (StructureMap in this case) made it painless for us to pull code apart into separate classes. The code was made easier to maintain by applying a few established object oriented design principles. Hopefully this example helped clarify the application of these principles. Your feedback is appreciated.&lt;/p&gt;

&lt;p&gt;For additional context, you can &lt;a href="http://github.com/jagregory/docu/commit/41bf6458ed4297a355400b0ea2c465a1511122b0" target="_blank"&gt;view the commit&lt;/a&gt; that contained the changes discussed above.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Real+World+Refactoring&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f06%2f28%2freal-world-refactoring.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f06%2f28%2freal-world-refactoring.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22485" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=WiQJ5sbwOfE:RqLY3lvu3yw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/WiQJ5sbwOfE" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/structuremap/default.aspx">structuremap</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/docu/default.aspx">docu</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/composition/default.aspx">composition</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/design/default.aspx">design</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/06/28/real-world-refactoring.aspx</feedburner:origLink></item><item><title>Integrating a custom test runner with TeamCity</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/ZmntUyppLaY/integrating-a-custom-test-runner-with-teamcity.aspx</link><pubDate>Thu, 11 Jun 2009 00:45:15 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21752</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=21752</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/06/10/integrating-a-custom-test-runner-with-teamcity.aspx#comments</comments><description>&lt;p&gt;JetBrains’ TeamCity build server provides a wealth of information about the tests that are run as part of your build. If you use one of the test runners that they support out of the box, you automatically get real-time individual test results, detailed timing reports, and historical performance metrics.&lt;/p&gt;  &lt;p&gt;Up until recently, all of the tests for my team were run through NUnit – C# unit tests, QUnit JavaScript tests, and integration tests. Since NUnit is natively supported by TeamCity, we got used to the rich test reporting. However, we recently started to integrate our automated acceptance tests into the build. Our acceptance tests are written using StoryTeller, which are executed using its own test runner. The StoryTeller test runner has slightly different behavior than the NUnit runner. For one, a failed assertion does NOT stop execution of a test – it continues executing so that a single test can have multiple failed assertions. We also have the ability to mark individual tests with their state in the development lifecycle: they start as &amp;quot;acceptance” tests when they are first defined, and then are marked as “regression” once all supporting code has been correctly implemented. The idea is that you can drive your development with failing acceptance tests until they pass, at which point they become regression tests. This is relevant because a failed acceptance test does NOT fail the build – only a failed regression test will fail the build.&lt;/p&gt;  &lt;p&gt;The StoryTeller test runner is a console application that will return an error code if any regression tests fail. It also generates an HTML report which contains the details for each test. Our initial attempt at integrating it into our build allowed us to fail the build if any test failed, but we didn’t get much feedback about why it failed. We would have to go searching through the build log messages or HTML report files for details.&lt;/p&gt;  &lt;p&gt;I created a new StoryTeller ITestListener (&lt;a href="http://storyteller.tigris.org/source/browse/storyteller/trunk/source/StoryTeller/Engine/TeamCityTestListener.cs?revision=401&amp;amp;view=markup" target="_blank"&gt;TeamCityTestListener&lt;/a&gt;) which is used by the StoryTeller runner to log test results. It writes the test details to the console using TeamCity’s &lt;a href="http://www.jetbrains.net/confluence/display/TCD4/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests" target="_blank"&gt;Service Message API&lt;/a&gt; (which &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/archive/2008/09/10/monkey-patching-rake-for-use-with-teamcity.aspx" target="_blank"&gt;I mentioned previously&lt;/a&gt;). TeamCity picks up these messages, and creates the nice individual test reports, complete with timing and history:&lt;/p&gt;  &lt;p&gt;&lt;img title="StoryTeller test results in TeamCity" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="378" alt="StoryTeller test results in TeamCity" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_4C7407A7.png" width="644" border="0" /&gt; &lt;/p&gt;  &lt;p&gt;Now we know exactly which tests failed, but we don’t know which assertions in the tests failed. As I mentioned, the complete details of the test execution are recorded in an HTML report. It’d be nice if we could view individual test reports right within TeamCity. Turns out, that is pretty easy to do as well. I followed the documentation for &lt;a href="http://www.jetbrains.net/confluence/display/TCD4/Including+Third-Party+Reports+in+the+Build+Results" target="_blank"&gt;Including Third-Party Reports in the Build Results&lt;/a&gt;, and added the following line to our &amp;lt;TEAMCITY&amp;gt;\.ServerConfig\.BuildServer\config\main-config.xml file:&lt;/p&gt;  &lt;div&gt;   &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;report-tab&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;title&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;StoryTeller&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;basePath&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;st-results&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;startPage&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;st-results.htm&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We now have a nice new StoryTeller tab next to the other build result tabs:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_2B14620B.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="247" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/joshuaflanagan/image_5F00_thumb_5F00_2E4649F3.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We configured the build to store all of the HTML reports as artifacts, and point our custom tab to the test results index HTML file generated by StoryTeller. Clicking the StoryTeller tab displays that index file with a color coded overview of all of the tests. Clicking a test brings up the report for that test so that I can see exactly which steps failed.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Integrating+a+custom+test+runner+with+TeamCity&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f06%2f10%2fintegrating-a-custom-test-runner-with-teamcity.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f06%2f10%2fintegrating-a-custom-test-runner-with-teamcity.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21752" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=ZmntUyppLaY:3U9vy-yIF2E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/ZmntUyppLaY" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/teamcity/default.aspx">teamcity</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/06/10/integrating-a-custom-test-runner-with-teamcity.aspx</feedburner:origLink></item><item><title>Let your Inversion of Control tool work for you</title><link>http://feedproxy.google.com/~r/JoshuaFlanagan/~3/RDnD6UmUtN8/let-your-inversion-of-control-tool-work-for-you.aspx</link><pubDate>Wed, 10 Jun 2009 03:58:51 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21691</guid><dc:creator>Joshua Flanagan</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://www.lostechies.com/blogs/joshuaflanagan/rsscomments.aspx?PostID=21691</wfw:commentRss><comments>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/06/09/let-your-inversion-of-control-tool-work-for-you.aspx#comments</comments><description>&lt;p&gt;If you are just starting out exploring use of an Inversion of Control tool (IoC), its very easy to go down the wrong path, and make things harder for yourself. Today I had a conversation with a bright developer who was feeling the pain because doing it all wrong. And just a month or so ago, I had the same conversation with another bright developer who was also doing it the same, wrong, way.&lt;/p&gt;  &lt;p&gt;The problem may be that people misinterpret the intent of an IoC tool. It is seen simply as a configuration tool – a way to swap out classes using some magical XML or a DSL. The thought is that as long as your code gets all of its dependencies out of the container, you can change the behavior just by configuring the container.&lt;/p&gt;  &lt;p&gt;And then you end up with code that looks like this:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:18f29b6a-df39-4f20-936e-f18674d4e5d4" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class OrderService : IOrderService
{
    private IRepository _repository;
    private ISystemClock _systemClock;

    public OrderService()
    {
        _repository = Container.Resolve&amp;lt;IRepository&amp;gt;();
        _systemClock = Container.Resolve&amp;lt;ISystemClock&amp;gt;();
    }
}

public class OrderController
{
    private IOrderService _orderService;

    public OrderController()
    {
        _orderService = Container.Resolve&amp;lt;IOrderService&amp;gt;();
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The OrderService needs an IRepository and an ISystemClock, so you pull them out of the container in the constructor. The OrderController needs an IOrderService, so you pull it out of the container in the constructor. You can now swap out actual implementations using some external configuration.&lt;/p&gt;

&lt;p&gt;Except now you’ve got this annoying dependency on the magical Container class. And maybe the Container has a dependency on an external XML file.&lt;/p&gt;

&lt;p&gt;And you discover that when you try to unit test your OrderService, you need to make sure you have a Container available, and that it has been configured to serve up whichever instances you want to use during testing.&lt;/p&gt;

&lt;p&gt;Your simple, plain-old CLR object (POCO) now has this deadweight Container dependency dragging it down. The Container requires extra care and feeding, in the form of configuration, and now it has infected your entire codebase.&lt;/p&gt;

&lt;p&gt;Hopefully, at this point you are feeling enough pain that you go seeking some advice, and hopefully you find out about auto-wiring.&lt;/p&gt;

&lt;p&gt;Any IoC tool worth using will support auto-wiring dependencies for objects retrieved from the container. This means that the tool will build up all of the necessary objects needed to satisfy a request. This allows you to rewrite the above code as:&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:05c5a713-dba3-4dae-9581-fb0dbafcc1b4" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class OrderService : IOrderService
{
    private readonly IRepository _repository;
    private readonly ISystemClock _systemClock;

    public OrderService(IRepository repository, ISystemClock systemClock)
    {
        _repository = repository;
        _systemClock = systemClock;
    }
}

public class OrderController
{
    private readonly IOrderService _orderService;

    public OrderController(IOrderService orderService)
    {
        _orderService = orderService;
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But where did the Container go? Exactly. The majority of your code should never have to deal with the container directly. Ideally, you make a single call to the container which builds up an object graph that implements your program. For a console application, you might make a call to the container once in your static Main method. For an MVC web application, you might make a call to the container at the beginning of each request to retrieve the appropriate Controller. The rest of your code is blissfully ignorant of the container. When something asks the container for an OrderController, the container will detect the dependency on the IOrderService. So it goes to build an OrderService, and detects the dependencies on the IRepository and ISystemClock. So it builds up those instances, and any dependencies they may have, and so on.&lt;/p&gt;

&lt;p&gt;By the way, my colleague &lt;a href="http://codebetter.com/blogs/jeremy.miller/" target="_blank"&gt;Jeremy Miller&lt;/a&gt; wrote this same post just a few months ago. But he assured me it was worth re-writing, because there are new people jumping on all the time, and they’re not likely to go back reading old blog posts. If you find yourself with the problem I describe above, go get the full details by reading his post about &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2009/01/07/autowiring-in-structuremap-2-5.aspx" target="_blank"&gt;auto-wiring in StructureMap&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One thing that I’ll add is that I’ve heard a lot of talk lately that “container” is really a misnomer for what an IoC tool does, and that it should be more appropriately referred to as a “composer”. I think this argument has merit, and wonder if the name may be contributing to people going down the wrong path described above. A “container” sounds like something that stores a bunch of stuff for you, and it is your job to get stuff out of it, hence the explicit calls to the Container littered throughout your code. A “composer” sounds like something that takes little pieces of functionality in your application and puts them together into a usable whole. The bad code example above reflects “container” thinking. The better code example reflects “composer” thinking.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Let+your+Inversion+of+Control+tool+work+for+you&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f06%2f09%2flet-your-inversion-of-control-tool-work-for-you.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fjoshuaflanagan%2farchive%2f2009%2f06%2f09%2flet-your-inversion-of-control-tool-work-for-you.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21691" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshuaFlanagan?a=RDnD6UmUtN8:JBTriHV_pHo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshuaFlanagan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/JoshuaFlanagan/~4/RDnD6UmUtN8" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/structuremap/default.aspx">structuremap</category><category domain="http://www.lostechies.com/blogs/joshuaflanagan/archive/tags/composition/default.aspx">composition</category><feedburner:origLink>http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/06/09/let-your-inversion-of-control-tool-work-for-you.aspx</feedburner:origLink></item></channel></rss>
