<?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.devmavens.com/~d/styles/itemcontent.css"?><rss version="2.0">
<channel>
    <title>DevMavens Feed</title>
    <link>http://DevMavens.com/</link>
    <description>DevMavens</description>
    <language>en-us</language>
    <docs>http://DevMavens.com/Rss</docs>
 
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.devmavens.com/Devmavens" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="devmavens" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>A bad test</title>
      <author>Oren Eini</author>
      <link>http://feedproxy.google.com/~r/AyendeRahien/~3/4w7JGnu5dpM/a-bad-test</link>
      <description>&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/A-bad-test_14ECA/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/A-bad-test_14ECA/image_thumb.png" width="953" height="327"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is a bad test, because what it does is ensuring that something &lt;em&gt;does not works&lt;/em&gt;. I just finished implementing the session.Advaned.Defer support, and this test got my attention by failing the build.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Bad &lt;/em&gt;test, you should be telling me when I broke something, not when I added new functionality.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AyendeRahien/~4/4w7JGnu5dpM" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/AyendeRahien/~3/4w7JGnu5dpM/a-bad-test"&gt;A bad test&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/AyendeRahien"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/egTHMtTkaA9ccixhb3JlZqM3Nho/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/egTHMtTkaA9ccixhb3JlZqM3Nho/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/egTHMtTkaA9ccixhb3JlZqM3Nho/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/egTHMtTkaA9ccixhb3JlZqM3Nho/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 18 May 2012 13:00:00 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/AyendeRahien/~3/4w7JGnu5dpM/a-bad-test</guid>
    </item>
 
    <item>
      <title>Common Design Patterns Presentations</title>
      <author>Steve Smith</author>
      <link>http://ardalis.com/common-design-patterns-presentations</link>
      <description>&lt;p&gt;This month I presented on Common Design Patterns at two regional events.&amp;nbsp; I’ve given this talk a few times before, and it continues to evolve.&amp;nbsp; The first one was on 4 May at &lt;a href="http://stirtrek.com/"&gt;Stir Trek&lt;/a&gt;, as a replacement talk for a cancellation.&amp;nbsp; I only had about 24 hours’ notice so I didn’t spend much time updating the talk, and in fact I had to rip out a bunch of stuff that was specific to the last event I gave it at or outdated information, so visually the slides at Stir Trek weren’t what I would consider up to par.&amp;nbsp; The second time I presented was last night at &lt;a href="http://migang.org"&gt;MIGANG&lt;/a&gt; in Michigan, and I had a chance to give the slides a bit more love and choose some appropriate imagery to support the concepts.&amp;nbsp; You can view the slides from the presentation (the second one) here:&lt;/p&gt; &lt;div style="width: 425px" id="__ss_12969230"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Common design patterns (migang 16 May 2012)" href="http://www.slideshare.net/ardalis/common-design-patterns-migang-16-may-2012"&gt;Common design patterns (migang 16 May 2012)&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse12969230" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=commondesignpatterns-migang2012-120517074812-phpapp02&amp;amp;stripped_title=common-design-patterns-migang-16-may-2012&amp;amp;userName=ardalis" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;embed name="__sse12969230" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=commondesignpatterns-migang2012-120517074812-phpapp02&amp;amp;stripped_title=common-design-patterns-migang-16-may-2012&amp;amp;userName=ardalis" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt; &lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/ardalis"&gt;Steven Smith&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt; &lt;p&gt;The presentation’s demo code is actually a fork of the &lt;a href="http://mvcmusicstore.codeplex.com/"&gt;MVC Music Store sample&lt;/a&gt; available on CodePlex.&amp;nbsp; You can download it as a zip or via Mercurial from the &lt;a href="http://mvcmusicstore.codeplex.com/SourceControl/network/forks/ssmith/MvcMusicStoreRepositoryPattern"&gt;MvcMusicStoreRepositoryPattern fork here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I did realize after talking to a couple of attendees last night that at one point I mentioned that the Design Patterns book was by Fowler.&amp;nbsp; I meant Gang of Four.&amp;nbsp; If you’re looking for good books on the patterns I discussed, and others, here are some good ones:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://amzn.to/95q9ux"&gt;Design Patterns&lt;/a&gt; – reference by Gang of Four&lt;/li&gt; &lt;li&gt;&lt;a href="http://amzn.to/aA4RS6"&gt;Head First Design Patterns&lt;/a&gt; – great learning book, highly recommended&lt;/li&gt; &lt;li&gt;&lt;a href="http://amzn.to/Aqs5qZ"&gt;Patterns of Enterprise Application Architecture&lt;/a&gt; – more patterns for use in enterprise applications by Fowler&lt;/li&gt; &lt;li&gt;&lt;a href="http://amzn.to/JViyKD"&gt;Domain Driven Design&lt;/a&gt; – builds on and introduces additional patterns&lt;/li&gt; &lt;li&gt;&lt;a href="http://amzn.to/JiQi73"&gt;Refactoring&lt;/a&gt; – reference by Fowler&lt;/li&gt; &lt;li&gt;&lt;a href="http://amzn.to/Ki7Zys"&gt;Working Effectively with Legacy Code&lt;/a&gt; – in my opinion this shows better how, when, and why to refactor code than Refactoring does&lt;/li&gt;&lt;/ul&gt; &lt;p&gt; And of course if you want to learn &lt;a href="http://www.pluralsight-training.net/microsoft/olt/Course/Toc.aspx?n=patterns-library"&gt;Design Patterns&lt;/a&gt; and the &lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=principles-oo-design"&gt;Principles of Object Oriented Design&lt;/a&gt; that they follow, you’ll find great Pluralsight courses on these topics.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kUwteonjYyrJb17g6ufL0QFkD8Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kUwteonjYyrJb17g6ufL0QFkD8Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kUwteonjYyrJb17g6ufL0QFkD8Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kUwteonjYyrJb17g6ufL0QFkD8Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.stevesmithblog.com/~ff/StevenSmith?a=w9Tz4qaBIIU:JvHipz04gV0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/StevenSmith?i=w9Tz4qaBIIU:JvHipz04gV0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevesmithblog.com/~ff/StevenSmith?a=w9Tz4qaBIIU:JvHipz04gV0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/StevenSmith?i=w9Tz4qaBIIU:JvHipz04gV0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.stevesmithblog.com/~ff/StevenSmith?a=w9Tz4qaBIIU:JvHipz04gV0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/StevenSmith?i=w9Tz4qaBIIU:JvHipz04gV0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/w9Tz4qaBIIU" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://ardalis.com/common-design-patterns-presentations"&gt;Common Design Patterns Presentations&lt;/a&gt; | &lt;a href="http://feeds.stevesmithblog.com/StevenSmith"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KUr0hK0Mp1oeFsqFlSOqR1FaOkw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KUr0hK0Mp1oeFsqFlSOqR1FaOkw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KUr0hK0Mp1oeFsqFlSOqR1FaOkw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KUr0hK0Mp1oeFsqFlSOqR1FaOkw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 17 May 2012 17:18:16 GMT</pubDate>
      <guid>http://ardalis.com/common-design-patterns-presentations</guid>
    </item>
 
    <item>
      <title>When using the Task Parallel Library, Wait() is a BAD warning sign</title>
      <author>Oren Eini</author>
      <link>http://feedproxy.google.com/~r/AyendeRahien/~3/71OP6uo3bTQ/when-using-the-task-parallel-library-wait-is-a-bad-warning-sign</link>
      <description>&lt;p&gt;Take a look at the following code:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Task ParseAsync(IPartialDataAccess source, IPartialDataAccess seed, Stream output, IEnumerable&amp;lt;RdcNeed&amp;gt; needList)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; Task.Factory.StartNew(() =&amp;gt;
    {
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; needList)
        {
            &lt;span class="kwrd"&gt;switch&lt;/span&gt; (item.BlockType)
            {
                &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Source:
                    source.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength)).Wait();
                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;
                &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Seed:
                    seed.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength)).Wait();
                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;
                &lt;span class="kwrd"&gt;default&lt;/span&gt;:
                    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotSupportedException();
            }
        }
    });
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Do you see the problem in here?&lt;/p&gt;
&lt;p&gt;It is a result of a code review comment about improper use of async in a project. This resulted in a lot of Task showing up in the return methods, but not in any measurable improvement in the actual codebase use of asynchronicity.&lt;/p&gt;
&lt;p&gt;The problem is that when you need to work with such things in C# 4.0, you have to do some annoying things to get the code to work properly. In particular, this method was modified to be:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Task ParseAsync(IPartialDataAccess source, IPartialDataAccess seed, Stream output, IList&amp;lt;RdcNeed&amp;gt; needList, &lt;span class="kwrd"&gt;int&lt;/span&gt; position = 0)
{
  &lt;span class="kwrd"&gt;if&lt;/span&gt;(position&amp;gt;= needList.Count)
  {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CompletedTask();
  }
  var item = needList[position];
  Task task;
            
  &lt;span class="kwrd"&gt;switch&lt;/span&gt; (item.BlockType)
  {
        &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Source:
            task = source.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength));
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Seed:
            task = seed.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength));
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;default&lt;/span&gt;:
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotSupportedException();
  }

  &lt;span class="kwrd"&gt;return&lt;/span&gt; task.ContinueWith(resultTask =&amp;gt;
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (resultTask.Status == TaskStatus.Faulted)
            resultTask.Wait(); &lt;span class="rem"&gt;// throws&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; ParseAsync(source, seed, output, needList, position + 1);
    }).Unwrap();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This code is more complex, but it is actually making proper use of the TPL. We have changed the loop into a recursive function, so we can take advantage of ContinueWith to the next iteration of the loop.&lt;/p&gt;
&lt;p&gt;And no, I can’t &lt;em&gt;wait&lt;/em&gt; to get to C# 5.0 and have proper await work.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AyendeRahien/~4/71OP6uo3bTQ" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/AyendeRahien/~3/71OP6uo3bTQ/when-using-the-task-parallel-library-wait-is-a-bad-warning-sign"&gt;When using the Task Parallel Library, Wait() is a BAD warning sign&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/AyendeRahien"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mB98uKArDQnHr51gsSoDFNuBA2o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mB98uKArDQnHr51gsSoDFNuBA2o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mB98uKArDQnHr51gsSoDFNuBA2o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mB98uKArDQnHr51gsSoDFNuBA2o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 17 May 2012 13:00:00 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/AyendeRahien/~3/71OP6uo3bTQ/when-using-the-task-parallel-library-wait-is-a-bad-warning-sign</guid>
    </item>
 
    <item>
      <title>Please Learn to Think about Abstractions</title>
      <author>Scott Hanselman</author>
      <link>http://feedproxy.google.com/~r/ScottHanselman/~3/nX2j1EGgKb4/PleaseLearnToThinkAboutAbstractions.aspx</link>
      <description>Jeff Atwood wrote a post called Please Don't Learn to Code and Zed Shaw wrote a post called Please Don't Become Anything, Especially Not A Programmer.  My wife lost her wedding ring down the drain. She freaked out and came running declaring that it &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/ScottHanselman/~3/nX2j1EGgKb4/PleaseLearnToThinkAboutAbstractions.aspx"&gt;Please Learn to Think about Abstractions&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/ScottHanselman"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-0ZpXXiSp4lNe28pVSC9Q2QSyF0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-0ZpXXiSp4lNe28pVSC9Q2QSyF0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-0ZpXXiSp4lNe28pVSC9Q2QSyF0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-0ZpXXiSp4lNe28pVSC9Q2QSyF0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 17 May 2012 04:05:18 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/ScottHanselman/~3/nX2j1EGgKb4/PleaseLearnToThinkAboutAbstractions.aspx</guid>
    </item>
 
    <item>
      <title>Why I Taught My Daughter To Code (A Little)</title>
      <author>Jon Galloway</author>
      <link>http://feedproxy.google.com/~r/jongalloway/~3/czEBCvaoVBE/why-i-taught-my-daughter-to-code-a-little.aspx</link>
      <description>&lt;h2&gt;Literacy&lt;/h2&gt;  &lt;p&gt;Imagine a world in which very few people knew how to read or write. You kept to certain parts of town because you couldn't read a map or a street sign. When you needed to sign a contract, you just asked what it said and had to take it on faith. A lot of your experience was based on legend and rumor. Books, and the information in them, were mystical. Sometimes you suspected they were being used against you, but you never really knew.&lt;/p&gt;  &lt;p&gt;There was definitely plenty of work around, but some high end jobs weren't remotely possible - not just clerical work, but professions that required a lot of information management, like the medical and legal professions.&lt;/p&gt;  &lt;h2&gt;Please don't tell me not to learn to code&lt;/h2&gt;  &lt;p&gt;Over this past year, there have been commentary back and forth on whether everyone should learn to code. A few free, interactive sites like &lt;a href="http://www.codecademy.com"&gt;Codecademy&lt;/a&gt; popped up which made it easy to start learning some basic coding. I was a big fan - I helped my eleven year old daughter go through it, and we both agreed it was great. More on that later.&lt;/p&gt;  &lt;p&gt;Then Codecademy launched &lt;a href="http://codeyear.com/"&gt;Code Year&lt;/a&gt; - a grand plan to teach hundreds of thousands of people to code. It was a big hit - even NYC's mayor signed up.&lt;/p&gt;  &lt;p&gt;But no good deed goes unpunished, and there's been some snarky criticism from - you guessed it - professional coders. The latest if Jeff Atwood's post, &lt;a href="http://www.codinghorror.com/blog/2012/05/please-dont-learn-to-code.html"&gt;Please Don't Learn To Code&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Hogwash. &lt;strong&gt;Learning some basic coding is an excellent investment of anyone's time&lt;/strong&gt;.&lt;/p&gt;  &lt;h2&gt;Easy on the Straw Men&lt;/h2&gt;  &lt;p&gt;It's &amp;quot;please don't hear what I'm not saying&amp;quot; time.&lt;/p&gt;  &lt;p&gt;I don't think that the general populace needs to be proficient at writing code. It would be silly to argue Mayor Bloomberg shouldn't be slinging Javascript on the job (as Jeff does). That's not at all the goal. Nobody's saying that everyone should become a programmer.&lt;/p&gt;  &lt;p&gt;What I - and others -are saying is that learning some basic coding skills is an excellent investment of anyone's time. I'll make two arguments:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Understanding computers (including all the computing devices and products that surround us) is of huge and growing benefit to everyone. &lt;/li&gt;    &lt;li&gt;Basic programming is an excellent way to gain some of that understanding. &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Computer Literacy as a Basic Life Skill - Right Now&lt;/h2&gt;  &lt;p&gt;Right now, pretty much every part of life is in some way affected by computers - most pretty heavily. Shopping, socializing, medicine, education, law, entertainment and more are all at the very least affected by computers and the internet. My three daughters had a use for basic computer skills long before math would do them any good.&lt;/p&gt;  &lt;p&gt;This only gets more intense with increasing age. Teenagers can greatly profit from computer expertise and tech savvy. It's hard to imagine a college program (at least one with any practical application) that didn't involve a hefty amount of computer usage - from basic internet research and word processing on up to simulation and research.&lt;/p&gt;  &lt;p&gt;Most careers (in the industrial world) involve some amount of information management, and workers in these professions who have some computer skill can often be a lot more effective. That includes areas where even a decade ago people might not have expected to see computers - agriculture, construction, family-run restaurants.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;I've talked with countless &amp;quot;civilians&amp;quot; who have profited from computer skills over the years&lt;/strong&gt; - a real estate appraiser who figured out how to automate using Excel and worked circles around his colleagues, film makers and musicians who figured out how to record, market and distribute on the internet, non-techies who sell things online, a school facilities manager who figured out how to cut costs significantly using computer security and automation.&lt;/p&gt;  &lt;p&gt;And many of those people had new doors and careers open to them due to their new-found computer skills. When the real estate market slowed down, the appraiser jumped right into a technology job. Heck, learning to code on my own - starting with my grade school's Apple II - gave me the option to jump into a computer career after I got out of the Navy (in a technical but not computer related field).&lt;/p&gt;  &lt;h2&gt;Computer Literacy as an Absolute Essential in the Very Near Future&lt;/h2&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;The future is already here — it's just not very evenly distributed.&amp;quot;&lt;/p&gt;    &lt;p&gt;- William Gibson&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It should be obvious to anyone paying attention that computers have become a huge part of our daily lives, and that trend is rapidly accelerating.&lt;/p&gt;  &lt;p&gt;I'm reading &lt;a href="http://www.amazon.com/gp/product/0307473333?ie=UTF8&amp;amp;tag=jongall-20&amp;amp;linkCode=shr&amp;amp;camp=213733&amp;amp;creative=393185&amp;amp;creativeASIN=0307473333&amp;amp;ref_=tmm_pap_title_0&amp;amp;qid=1336467157&amp;amp;sr=8-1"&gt;Physics of the Future&lt;/a&gt; (Michio Kaku). It's a fascinating book in which Michio points to obvious trends and extrapolates where things are going in the near future. In many cases, even a very conservative estimate - or even a look around - shows that every part of life will soon involve interacting with computers and the internet. He points out that global powers during World War II would have killed for the computational power in a simple musical birthday card. Now, we just throw them away. Average mobile phones rival supercomputers from the not-too-distant past, and they're connected to a growing internet and GPS satellites. In the next few decades, computers will continue to shrink and become integrated into everything we interact with.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The quality of our everyday lives will be greatly affected by how we interact with computers. &lt;/strong&gt;&lt;strong&gt;How should that interaction take place?&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;Magical! Or, Should We See Computers as Products or Tools?&lt;/h2&gt;  &lt;p&gt;Technology companies work hard to package technology so that it can be used naturally, so consumers won't have to think or fiddle with details. This is a good thing. Anyone working in technology should be focused, consumed with the challenge of exposing &lt;em&gt;the possible&lt;/em&gt; as &lt;em&gt;the natural&lt;/em&gt;. We should be doing this not just because it's a worthy goal, but because it makes good business sense - friendly products sell.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;But it is not in the average consumer's interest for them to blindly buy into this magical experience.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Think about the historical progress in how informed consumers approach medicine. In ancient times, mystics sold magic and consumers had no real insight into what they were buying. Over the centuries, the public has gained a much more informed view of science and medicine, and this is of huge benefit to them as consumers. We expect to see evidence, we read about product recalls, and the market for doctors who sell amulets and snake oils is pretty small. This applies to other areas of life, as well. While I could get around in a car I thought was powered by tiny horses, I'd be unlikely to make wise decisions regarding the purchase and repairs to said car. An informed approach to modern life helps.&lt;/p&gt;  &lt;p&gt;&lt;a title="2012-05-16 15h06_11" href="http://www.flickr.com/photos/36836555@N00/7212015394/"&gt;&lt;img border="0" alt="2012-05-16 15h06_11" src="http://farm8.static.flickr.com/7240/7212015394_78a00ca144.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now think about the consumer approach to computer products. &lt;/p&gt;  &lt;p&gt;Think about how computers and technology are shown in movies and TV. &lt;/p&gt;  &lt;p&gt;Think about how helpless your relatives and neighbors feel when they're buying techy products, or when something doesn't work. &lt;/p&gt;  &lt;p&gt;Think about a friend or relative who paid too much for a website that never worked right.&lt;/p&gt;  &lt;p&gt;Ah, but you may be thinking about a favorite company who sells you magical products right now, or runs some of your favorite websites, or sells you apps or movies. Well marketed brands that have built reputations for quality and ease of use have helped uninformed consumers navigate the technology landscape, but keep in mind that these companies have divided interests. It's their job. They want to sell you things, and their stockholders demand that they bring in as much profit as they can from those sales. &lt;strong&gt;Mindless and uninformed&lt;/strong&gt; brand loyalty is not only expensive, it's by nature counter to your interests. It's no way to live - and thrive - in a digital world.&lt;/p&gt;  &lt;h2&gt;Computer Literacy as a Leadership Requirement&lt;/h2&gt;  &lt;p&gt;The basic level of technical understanding that we expect of our leaders must grow with time in order for them to govern. We expect them to understand our legal system, but we also expect they should know that medicines are chemicals which influence the biological processes in our bodies, that electricity powers lightbulbs and is transmitted over an electrical power grid, that mobile phones have radios in them, etc. &lt;strong&gt;I'd be scared to hear that our leadership didn't have a very basic understanding of our modern world.&lt;/strong&gt; They write and enforce laws and policies that greatly impact our lives, so they need to have a clue about the world we live in.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In the same way, leaders who see computers as magic boxes, coders as wizards, and computer code as incantations can't effectively govern.&lt;/strong&gt; They can't set policy, they can't have informed legal opinions, they have no framework for evaluating whether information being fed to them is makes any sense (or even knowing if they should ask). &lt;/p&gt;  &lt;p&gt;Leadership requires understanding, and more, it requires - well, a sense of direction. The future is going to include more and more technology, and leaders who don't understand the present or even have a rough idea of the road ahead are a menace.&lt;/p&gt;  &lt;h2&gt;Computer Literacy as an Educational Oversight&lt;/h2&gt;  &lt;p&gt;I've been describing why non-techies can benefit from some computer literacy. Unfortunately, they won't get it in from our schools.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Computer literacy is undoubtedly of more use to most people than the foreign languages most high schools require&lt;/strong&gt; (I want those 4 years I spent on high school French back). I have rich conversations with people worldwide thanks to the internet and automated translations, not any time I've spent studying languages.&lt;/p&gt;  &lt;p&gt;Though it may offend, &lt;strong&gt;computer skills are of more use to the huge majority than mathematics including and beyond first year algebra.&lt;/strong&gt; Most people will rarely if ever use algebra; everyone uses computers. &lt;/p&gt;  &lt;p&gt;Consider this: in the off chance that the average farmer / dentist / lawyer / car mechanic / stay at home parent / author / teacher / etc. needs to solve an algebra problem, they can &lt;a href="http://www.bing.com/search?q=3x+%2B+7y+%3D+4y+-+35&amp;amp;qs=n&amp;amp;form=QBRE&amp;amp;pq=3x+%2B+7y+%3D+4y+-+35&amp;amp;sc=0-11&amp;amp;sp=-1&amp;amp;sk="&gt;punch it into the search engine and get the answer&lt;/a&gt;: &lt;a href="http://www.wolframalpha.com/input/?i=3x+%2b+7y+%3d+4y+-+35&amp;amp;incTime=true"&gt;3x + 7y = 4y - 35&lt;/a&gt;. Or, more likely, just ask their phone.&lt;/p&gt;  &lt;p&gt;The same goes for so many things we devote educational time to. Does the average high school graduate remember anything important about titration or Augustus or sentence diagram? Titian or Taft? Or even remember how WWI started? Does it matter when they can just look it up on Wikipedia?&lt;/p&gt;  &lt;p&gt;I'm all in favor a balanced education. I got a B.S. Physics (with honors) from Annapolis and went through the US Navy Nuclear Power program (a very rigorous engineering program) following that. My parents were both school teachers. My wife and I homeschool our daughters and put a very high priority on their education. I see education is important, and I think STEM is an important priority. &lt;/p&gt;  &lt;p&gt;But in the broader perspective, our educational priorities are often focused on a historical ideal, completely out of touch with a world in which nearly everyone interacts regularly with computers that most people barely understand.&lt;/p&gt;  &lt;p&gt;This is a much bigger discussion, but here's the main takeaway: after thousands of hours in the classroom, our students emerge unempowered into an increasingly digital world. &lt;strong&gt;We're on our own here.&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;Excess Capacity: Oh, the Hours We Throw Away&lt;/h2&gt;  &lt;p&gt;Fine, most people could benefit from some computer literacy. But who has the time?&lt;/p&gt;  &lt;p&gt;I don't buy it. We as a society throw away countless hours on games, entertainment, and apparently even tracking the adventures of someone called Snooki. We make video mashups and silly tumblogs and meme pictures of cats. We catalog &lt;a href="http://en.wikipedia.org/wiki/Pok%C3%A9mon"&gt;Pokémon&lt;/a&gt;. We read books about vampires romancing high school girls. We write long blog posts.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;We have the time.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We have a ridiculous amount of leisure time, hours we just throw away because we can't think of anything better to do.&lt;/p&gt;  &lt;h2&gt;Basic Coding as a Gateway To Basic Computer Literacy&lt;/h2&gt;  &lt;p&gt;While it might make sense, I'm not proposing citizens spend a mandatory two years in the &amp;quot;Get Smart About Computers&amp;quot; corps. I'm just proposing that: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Non-techies consider spending a few hours learning how computers work. &lt;/li&gt;    &lt;li&gt;Techies encouraging them - and not actively discouraging them ! Sheesh! &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Thankfully, getting a basic idea of how computers work has gotten incredibly easy. Sites like &lt;a href="http://www.codecademy.com/"&gt;Codecademy make it easy to learn&lt;/a&gt; - hands on - how computers work. These lessons are hands-on, and they're practical. You learn web fundamentals and how to build a simple website. This is empowering stuff. It's a great way to start the journey from a powerless consumer to a contributor, or at least informed consumer. It's not time consuming, and it's free.&lt;/p&gt;  &lt;p&gt;&lt;a title="2012-05-16 13h21_50" href="http://www.flickr.com/photos/36836555@N00/7211495278/"&gt;&lt;img border="0" alt="2012-05-16 13h21_50" src="http://farm6.static.flickr.com/5315/7211495278_f976739f30.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Maybe some of the negative reactions from coders to the Code Year phenomenon have come from not bothering to actually &lt;a href="http://www.codecademy.com/tracks/code-year"&gt;read what's in the classes&lt;/a&gt; and assuming that the goal was to turn a bunch of people into programmers. Maybe.&lt;/p&gt;  &lt;h2&gt;Case Study: Rosemary, Champion of the World (and my daughter)&lt;/h2&gt;  &lt;p&gt;This past year, my daughter asked me if I could teach her computers. I talked to my wife and rolled it into her school plan. We had ten lessons. During this time, we worked did the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;We worked through the &lt;a href="http://www.codecademy.com/courses/programming-intro?curriculum_id=4f4b35445cb288000300000c"&gt;Getting Started With Programming section&lt;/a&gt; of the Codecademy Javascript Fundamentals course. She did all the work on her own, and when she got stuck I would have her re-read the instructions out loud. She'd say &amp;quot;Oh! I should have read more carefully!&amp;quot; and move on. She learned some basic loops and conditionals - nothing difficult. I gave her at test on &lt;a href="http://repl.it/"&gt;repl.it&lt;/a&gt; where she wrote a loop from 1 to 25, outputting either &amp;quot;You are too young to drive a car!&amp;quot; or &amp;quot;Your age is 20, you can drive a car!&amp;quot; &lt;/li&gt;    &lt;li&gt;She asked how the internet works, so &lt;a href="http://www.youtube.com/watch?v=qv0XCaUkfNk"&gt;we watched a video on YouTube&lt;/a&gt; about how the internet works. Then we went on a field trip to our router, and we talked about how to &amp;quot;fix the internet&amp;quot; when it's not working. &lt;/li&gt;    &lt;li&gt;She asked about making a web page, and how web pages work. We played with browser tools (Chrome and IE) and she learned the difference between HTML, CSS, and Javascript. I let her recolor my webpage pink, and we went to CNN and put her picture and the headline of her choice in the headlines. &lt;/li&gt;    &lt;li&gt;She asked about making a computer game. We talked about why that would take some work, and planned to do that when we started back up in the semester. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a title="2012-05-16 14h05_30" href="http://www.flickr.com/photos/36836555@N00/7211722630/"&gt;&lt;img border="0" alt="2012-05-16 14h05_30" src="http://farm6.static.flickr.com/5464/7211722630_8b9d246f62_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This was fun. We both had a good time. She asked questions that wouldn't have come up otherwise, and she wouldn't have been interested in otherwise.&lt;/p&gt;  &lt;p&gt;More importantly, after only 8 or so hours, I noticed she saw the world differently. She had ideas about what computers should do. She laughed when computers did silly things on TV. She read error messages and solved problems in an intelligent way. She keeps asking about building a computer game.&lt;/p&gt;  &lt;p&gt;She understands that there's no reason that girls can't have fun with computers, too.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;From a time investment of about 8 hours.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This started with writing some Javascript and HTML. That was critical because it helped her understand how computers work. She learned that they were unthinking and unforgiving in the way they followed her instructions. More importantly, she learned that they would do what she told her if she learned their language (in this case, some basic Javascript).&lt;/p&gt;  &lt;h2&gt;Case Study: The Judge&lt;/h2&gt;  &lt;p&gt;In a funny bit of timing, just last night I read about &lt;a href="https://plus.google.com/110412141990454266397/posts/fk5VXPpiQZR#110412141990454266397/posts/fk5VXPpiQZR"&gt;the judge on the Oracle / Google trial was able to make an informed decision about a Java function&lt;/a&gt; because he'd been -shocker - learning some Java. It was something that would have seemed obvious to most programmers, but was delightfully refreshing &lt;a href="http://www.groklaw.net/article.php?story=20120515120106322"&gt;to hear in a court&lt;/a&gt;.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Now here is a later followup where the Judge slams Oracle:      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;Judge: We heard the testimony of Mr. Bloch. I couldn't have told you the first thing about Java before this problem. I have done, and still do, a significant amount of programming in other languages. I've written blocks of code like rangeCheck a hundred times before. I could do it, you could do it. The idea that someone would copy that when they could do it themselves just as fast, it was an accident. There's no way you could say that was speeding them along to the marketplace. You're one of the best lawyers in America, how could you even make that kind of argument?      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;Oracle: I want to come back to rangeCheck.      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;Judge: rangeCheck! All it does is make sure the numbers you're inputting are within a range, and gives them some sort of exceptional treatment. That witness, when he said a high school student could do it...&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So here's a judge who's able to make an informed decision about a technology case. What's more shocking is that this is news.&lt;/p&gt;  &lt;h2&gt;Some Objections&lt;/h2&gt;  &lt;h3&gt;Shouldn't everyone learn plumbing, too?&lt;/h3&gt;  &lt;p&gt;Jeff's been having fun equating the &amp;quot;learn to code&amp;quot; movement with &amp;quot;learn plumbing!&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codinghorror.com/.a/6a0120a85dcdae970b01676680302e970b-800wi" /&gt;&lt;/p&gt;  &lt;p&gt;This is one of those fun arguments that sounds good but falls apart after a moment of thought. What would the return on investment be - both in cost and time - for your average person to learn more about plumbing than working a plunger? How often do they work with plumbing in a way that would benefit from a deeper understanding?&lt;/p&gt;  &lt;p&gt;How often do most people work with computers, smartphones, and internet sites in a way that would benefit from knowing a bit more?&lt;/p&gt;  &lt;h3&gt;Not more code! The world needs less code!&lt;/h3&gt;  &lt;p&gt;This is a bad argument for three reasons:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;This is a coder's argument to other coders. Solving your application's issues is often best solved by thinking, not mindless coding - granted. That has nothing to do with whether it's worthwhile for your average person to learn about how computers work. &lt;/li&gt;    &lt;li&gt;It's - perhaps unintentionally - elitist. We nerds have a huge advantage in dealing with the computers that surround us. Telling the rest of the world that they can't join in, or acting like it's harder than it is, is just wrong. &lt;/li&gt;    &lt;li&gt;It assumes that amateurs won't be writing code anyways. I've seen tons of code over the years written by people who had a problem to solve. They cobbled it together from internet searches. It was inelegant, but it worked in that it solved their problem. There are a lot of populist pseudocoding tools out there - think of &lt;a href="http://ifttt.com/wtf"&gt;ifttt&lt;/a&gt; or the use of countless Wordpress plugins - that let real people solve real problems without having to wait for nerds to get involved. They'll do what they need to do, the question is whether we'll encourage them and help them find the structure. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Fine, learn computer literacy, not coding!&lt;/h3&gt;  &lt;p&gt;This is at least something. The problem here is twofold:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It assumes people know what questions to ask, or how to ask them. As long as they see computers and the internet as mystical boxes full of magic, that's not the case. I'm continually helping people solve problems by prompting them to actually read what a program or web page is telling them (and saying that computers and web pages need to give better messages or not require input is irrelevant).      &lt;br /&gt;      &lt;br /&gt;Without knowing the fundamental differences between how computers and people think, people resort to just yelling louder in their own language.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;It assumes we know what people need to learn. That's only kind of true. Often the approaches I've seen here come down to teaching them how to use a particular product or software package, which is definitely not &amp;quot;teaching a man to fish.&amp;quot; Real problem solving skills in the technology world come down to thinking systematically and rationally about technology, which requires some basic understanding. &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Where Next?&lt;/h2&gt;  &lt;p&gt;If you don't know how to code, get started. &lt;a href="http://www.codecademy.com/#!/exercises/0"&gt;It's free, fun and easy&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;If you know how to code, encourage others around you when they want to learn. Odds are, someone did that for you a while back.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8488927" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=czEBCvaoVBE:QQouEWlwTkI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=czEBCvaoVBE:QQouEWlwTkI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=czEBCvaoVBE:QQouEWlwTkI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=czEBCvaoVBE:QQouEWlwTkI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=czEBCvaoVBE:QQouEWlwTkI:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=czEBCvaoVBE:QQouEWlwTkI:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=czEBCvaoVBE:QQouEWlwTkI:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/czEBCvaoVBE" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/jongalloway/~3/czEBCvaoVBE/why-i-taught-my-daughter-to-code-a-little.aspx"&gt;Why I Taught My Daughter To Code (A Little)&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/jongalloway"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2HbPlaQMpDP91CBXg6ExfXl-iio/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2HbPlaQMpDP91CBXg6ExfXl-iio/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2HbPlaQMpDP91CBXg6ExfXl-iio/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2HbPlaQMpDP91CBXg6ExfXl-iio/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 17 May 2012 02:11:37 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/jongalloway/~3/czEBCvaoVBE/why-i-taught-my-daughter-to-code-a-little.aspx</guid>
    </item>
 
    <item>
      <title>DropDownList and SelectListItem Array Item Updates in MVC</title>
      <author>Rick Strahl</author>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/JoO8wkUD26c/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC</link>
      <description>&lt;p&gt;So I ran into an interesting behavior today as I deployed my first MVC 4 app tonight. I have a list form that has a filter drop down that allows selection of categories. This list is static and rarely changes so rather than loading these items from the database each time I load the items once and then cache the actual SelectListItem[] array in a static property.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/DropDownList-and-SelectItemArray-Items-g_14142/DropDown_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DropDown" border="0" alt="DropDown" src="http://www.west-wind.com/Weblog/images/200901/Windows-Live-Writer/DropDownList-and-SelectItemArray-Items-g_14142/DropDown_thumb.png" width="255" height="130"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;However, when we put the site online tonight we immediately noticed that the drop down list was coming up with pre-set values that randomly changed. Didn't take me long to trace this back to the cached list of SelectListItem[]. Clearly the list was getting updated - apparently through the model binding process in the selection postback.&lt;/p&gt; &lt;p&gt;To clarify the scenario here's the drop down list definition in the Razor View:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;Html.DropDownListFor(mod =&amp;gt; mod.QueryParameters.Category, &lt;strong&gt;Model.CategoryList&lt;/strong&gt;, &lt;span style="color: #a31515"&gt;"All Categories"&lt;/span&gt;)&lt;/pre&gt;
&lt;p&gt;where Model.CategoryList gets set with:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;HttpPost&lt;/span&gt;]
[&lt;span style="color: #2b91af"&gt;CompressContent&lt;/span&gt;]
&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;List(&lt;span style="color: #2b91af"&gt;MessageListViewModel &lt;/span&gt;model)
{
    InitializeViewModel(model);

&lt;span style="color: #2b91af"&gt;    busEntry &lt;/span&gt;entryBus = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;busEntry&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;entries = entryBus.GetEntryList(model.QueryParameters);

    model.Entries = entries;
    model.DisplayMode = &lt;span style="color: #2b91af"&gt;ApplicationDisplayModes&lt;/span&gt;.Standard;
       
&lt;strong&gt;    model.CategoryList = &lt;span style="color: #2b91af"&gt;AppUtils&lt;/span&gt;.GetCachedCategoryList(&lt;/strong&gt;);&lt;br&gt;
&lt;span style="color: blue"&gt;    return &lt;/span&gt;View(model);
}
&lt;/pre&gt;
&lt;p&gt;The AppUtils.GetCachedCategoryList() method gets the cached list or loads the list on the first access. The code to load up the list is housed in a Web utility class. The method looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Returns a static category list that is cached
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;[] GetCachedCategoryList()
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(_CategoryList != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList;

    &lt;span style="color: blue"&gt;lock &lt;/span&gt;(_SyncLock)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(_CategoryList != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList;
        
        &lt;span style="color: blue"&gt;var &lt;/span&gt;catBus = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;busCategory&lt;/span&gt;();
        &lt;span style="color: blue"&gt;var &lt;/span&gt;categories = catBus.GetCategories().ToList();


        &lt;span style="color: green"&gt;// Turn list into a SelectItem list            
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;catList= categories
                         .Select(cat =&amp;gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;() { Text = cat.Name, Value = cat.Id.ToString() })
                         .ToList();

        catList.Insert(0, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;()
        {
            Value = ((&lt;span style="color: blue"&gt;int&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;SpecialCategories&lt;/span&gt;.AllCategoriesButRealEstate).ToString(),
            Text = &lt;span style="color: #a31515"&gt;"All Categories except Real Estate"
        &lt;/span&gt;});
        catList.Insert(1, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;()
        {
            Value = &lt;span style="color: #a31515"&gt;"-1"&lt;/span&gt;,
            Text = &lt;span style="color: #a31515"&gt;"--------------------------------"                    
        &lt;/span&gt;});
        
        _CategoryList = catList.ToArray();
    }

    &lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList;
}
&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;[] _CategoryList ;&lt;/pre&gt;
&lt;p&gt;This seemed normal enough to me - I've been doing stuff like this forever caching smallish lists in memory to avoid an extra trip to the database. This list is used in various places throughout the application - for the list display and also when adding new items and setting up for notifications etc..&lt;/p&gt;
&lt;h3&gt;Watch that ModelBinder!&lt;/h3&gt;
&lt;p&gt;However, it turns out that this code is clearly causing a problem. It appears that the model binder on the [HttpPost] method is actually updating the list that's bound to and changing the actual entry item in the list and setting its selected value. If you look at the code above I'm not setting the SelectListItem.Selected value anywhere - the only place this value can get set is through ModelBinding. Sure enough when stepping through the code I see that when an item is selected the actual model - model.CategoryList[x].Selected - reflects that.&lt;/p&gt;
&lt;p&gt;This is bad on several levels: First it's obviously affecting the application behavior - nobody wants to see their drop down list values jump all over the place randomly. But it's also a problem because the array is getting updated by multiple ASP.NET threads which likely would lead to odd crashes from time to time. Not good!&lt;/p&gt;
&lt;p&gt;In retrospect the modelbinding behavior makes perfect sense. The actual items and the Selected property is the ModelBinder's way of keeping track of one or more selected values. So while I assumed the list to be read-only, the ModelBinder is actually updating it on a post back producing the rather surprising results. Totally missed this during testing and is another one of those little - "Did you know?" moments.&lt;/p&gt;
&lt;p&gt;So, is there a way around this? Yes but it's maybe not quite obvious. I can't change the behavior of the ModelBinder, but I can certainly change the way that the list is generated. Rather than returning the cached list, I can return a brand new cloned list from the cached items like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Returns a static category list that is cached
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;[] GetCachedCategoryList()
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(_CategoryList != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color: green"&gt;// Have to create new instances via projection
        // to avoid ModelBinding updates to affect this
        // globally
        &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;_CategoryList
                    .Select(cat =&amp;gt; &lt;strong&gt;&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;()
                                   {
                                       Value = cat.Value,
                                       Text = cat.Text
                                   }&lt;/strong&gt;)
                    .ToArray();
    }
&lt;/pre&gt;&lt;pre class="code"&gt;    …&lt;/pre&gt;&lt;pre class="code"&gt;}&lt;/pre&gt;&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;The key is that newly created instances of SelectListItems are returned not just filtered instances of the original list. The key here is 'new instances' so that the ModelBinding updates do not update the actual static instance. The code above uses LINQ and a projection into new SelectListItem instances to create this array of fresh instances. And this code works correctly - no more cross-talk between users.&lt;/p&gt;
&lt;p&gt;Unfortunately this code is also less efficient - it has to reselect the items and uses extra memory for the new array. Knowing what I know now I probably would have not cached the list and just take the hit to read from the database. If there is even a possibility of thread clashes I'm very wary of creating code like this. But since the method already exists and handles this load in one place this fix was easy enough to put in.&lt;/p&gt;
&lt;p&gt;Live and learn. It's little things like this that can cause some interesting head scratchers sometimes…&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2012&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=MVC'&gt;MVC&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=ASP.NET'&gt;ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=.NET'&gt;.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;
&lt;a href="https://twitter.com/share" class="twitter-share-button" data-text="DropDownList and SelectListItem Array Item Updates in MVC" data-via="RickStrahl" data-lang="en" data-hashtags="" data-url="http://www.west-wind.com/weblog/posts/2012/May/16/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC"&gt;Tweet&lt;/a&gt;
&lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;

&lt;g:plusone size="medium" href="http://www.west-wind.com/weblog/posts/2012/May/16/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC" "&gt;&lt;/g:plusone&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;

&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=JoO8wkUD26c:sDUgFyaNsuk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=JoO8wkUD26c:sDUgFyaNsuk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=JoO8wkUD26c:sDUgFyaNsuk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=JoO8wkUD26c:sDUgFyaNsuk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/JoO8wkUD26c" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/RickStrahl/~3/JoO8wkUD26c/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC"&gt;DropDownList and SelectListItem Array Item Updates in MVC&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/RickStrahl"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dHYJbBrYCa5gGxkkv1McqyRN_pE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dHYJbBrYCa5gGxkkv1McqyRN_pE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dHYJbBrYCa5gGxkkv1McqyRN_pE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dHYJbBrYCa5gGxkkv1McqyRN_pE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 16 May 2012 20:44:00 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/RickStrahl/~3/JoO8wkUD26c/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC</guid>
    </item>
 
    <item>
      <title>File System Wrappers for Unit Testing in C#</title>
      <author>Roy Osherove</author>
      <link>http://feedproxy.google.com/~r/Iserializable/~3/FyLnPFeM8PQ/file-system-wrappers-for-unit-testing-in-c.html</link>
      <description>&lt;p&gt;I&amp;#8217;ve asked this on twitter, and here&amp;#8217;s what I got:&lt;/p&gt;
&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tathamoddie/System.IO.Abstractions"&gt;System.IO.Abstractions&lt;/a&gt; (looks pretty deep)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://systemwrapper.codeplex.com/"&gt;SystemWrapper&lt;/a&gt;&amp;nbsp;(I&amp;#8217;m not crazy about the file system being used as a mock API)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bugsquash.blogspot.de/2008/03/injectable-file-adapters.html"&gt;Something older&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d take a look at the first on the list first, if only for it being on github as a sign of advancement.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=FyLnPFeM8PQ:RPE0YwFAaxY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=FyLnPFeM8PQ:RPE0YwFAaxY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=FyLnPFeM8PQ:RPE0YwFAaxY:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?i=FyLnPFeM8PQ:RPE0YwFAaxY:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Iserializable/~4/FyLnPFeM8PQ" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/Iserializable/~3/FyLnPFeM8PQ/file-system-wrappers-for-unit-testing-in-c.html"&gt;File System Wrappers for Unit Testing in C#&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/Iserializable"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Nj18xdHlFtFbp-Chf2HS_wzh_tE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Nj18xdHlFtFbp-Chf2HS_wzh_tE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Nj18xdHlFtFbp-Chf2HS_wzh_tE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Nj18xdHlFtFbp-Chf2HS_wzh_tE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 16 May 2012 16:29:18 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/Iserializable/~3/FyLnPFeM8PQ/file-system-wrappers-for-unit-testing-in-c.html</guid>
    </item>
 
    <item>
      <title>Test Driven Validation Logic with Extract &amp; Override</title>
      <author>Roy Osherove</author>
      <link>http://feedproxy.google.com/~r/Iserializable/~3/Mw79eHhnr9U/test-driven-validation-logic-with-extract-override.html</link>
      <description>&lt;p&gt;In the NerdDinner project, &lt;a href="http://nerddinner.codeplex.com/SourceControl/changeset/view/70027#874462"&gt;there&amp;#8217;s this amazing test&lt;/a&gt;&amp;nbsp;(see the bottom, second one).&lt;/p&gt;
&lt;p&gt;There are so many things wrong here:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is exactly correct about these properties?&lt;/li&gt;
&lt;li&gt;Many magic values&lt;/li&gt;
&lt;li&gt;Multiple tests in a single test&lt;/li&gt;
&lt;li&gt;if it fails, &amp;nbsp;its hard to find out why&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s how I would approach this kind of validation logic:&lt;/p&gt;
&lt;p&gt;use Extract and override, with the test setting the flags for all &amp;#8216;other&amp;#8217; validation functions except the one I&amp;#8217;m testing right now. and I&amp;#8217;d at least have two tests for each validation logic. This can also be accomplished with multiple classes and an interface, but I find the tests this way are more readable.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/2709023.js?file=gistfile1.cs"&gt;&lt;/script&gt;
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=Mw79eHhnr9U:00Ngy0nM2VI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=Mw79eHhnr9U:00Ngy0nM2VI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=Mw79eHhnr9U:00Ngy0nM2VI:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?i=Mw79eHhnr9U:00Ngy0nM2VI:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Iserializable/~4/Mw79eHhnr9U" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/Iserializable/~3/Mw79eHhnr9U/test-driven-validation-logic-with-extract-override.html"&gt;Test Driven Validation Logic with Extract &amp; Override&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/Iserializable"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zqoLWJoMnkGAJz_mRPT63AE0a6g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zqoLWJoMnkGAJz_mRPT63AE0a6g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zqoLWJoMnkGAJz_mRPT63AE0a6g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zqoLWJoMnkGAJz_mRPT63AE0a6g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 16 May 2012 13:24:38 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/Iserializable/~3/Mw79eHhnr9U/test-driven-validation-logic-with-extract-override.html</guid>
    </item>
 
    <item>
      <title>Reviewing RavenDB app: ReleaseCandidateTracker</title>
      <author>Oren Eini</author>
      <link>http://feedproxy.google.com/~r/AyendeRahien/~3/-b65I8jNg9I/reviewing-ravendb-app-releasecandidatetracker</link>
      <description>&lt;p&gt;&lt;a href="https://github.com/SzymonPobiega/ReleaseCandidateTracker"&gt;ReleaseCandidateTracker&lt;/a&gt; is a new RavenDB based application by Szymon Pobiega. I reviewed version 5f7e42e0fb1dea70e53bace63f3e18d95d2a62dd. At this point, I don’t know anything about this application, including what exactly it means, Release Tracking.&lt;/p&gt; &lt;p&gt;I downloaded the code and started VS, there is one project in the solution, which is already a Good Thing. I decided to randomize my review approach and go and check the Models directory first. &lt;/p&gt; &lt;p&gt;Here is how it looks:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_1.png" width="983" height="671"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is interesting for several reasons. First, it looks like it is meant to keep a record of all deployments to multiple environments, and that you can lookup the history of each deployment both on the environment side and on the release candidate side.&lt;/p&gt; &lt;p&gt;Note that we use rich models, which have collections in them. In fact, take a look at this method:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_2.png" width="1081" height="349"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Which calls to this method:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_3.png" width="602" height="243"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You know what the &lt;em&gt;really&lt;/em&gt; fun part about this? &lt;/p&gt; &lt;p&gt;It ain’t relational model. There is &lt;em&gt;no cost &lt;/em&gt;of actually making all of these calls!&lt;/p&gt; &lt;p&gt;Next, we move to the Infrastructure folder, where we have a couple of action results and the RavenDB management stuff. Here it how RCT uses RavenDB:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Database
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IDocumentStore storeInstance;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IDocumentStore Instance
    {
        get
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (storeInstance == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span class="str"&gt;"Document store has not been initialized."&lt;/span&gt;);
            }
            &lt;span class="kwrd"&gt;return&lt;/span&gt; storeInstance;
        }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize()
    {
        var embeddableDocumentStore = &lt;span class="kwrd"&gt;new&lt;/span&gt; EmbeddableDocumentStore {DataDirectory = &lt;span class="str"&gt;@"~\App_Data\Database"&lt;/span&gt;};
        embeddableDocumentStore.Initialize();
        storeInstance = embeddableDocumentStore;
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is using an embedded database to do that, which makes it very easy to use the app. Just hit F5 and go. In fact, if we do, we see the fully functional website, which is quite awesome &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/wlEmoticon-smile_2.png"&gt;.&lt;/p&gt;
&lt;p&gt;Let us move to seeing how we are managing the sessions:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BaseController : Controller
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IDocumentSession DocumentSession { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; CandidateService CandidateService { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; ScriptService ScriptService { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnActionExecuting(ActionExecutingContext filterContext)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (filterContext.IsChildAction)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt;;
        }
        DocumentSession = Database.Instance.OpenSession();
        CandidateService = &lt;span class="kwrd"&gt;new&lt;/span&gt; CandidateService(DocumentSession);
        ScriptService = &lt;span class="kwrd"&gt;new&lt;/span&gt; ScriptService(DocumentSession);
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnActionExecuting(filterContext);
    }
    
    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnActionExecuted(ActionExecutedContext filterContext)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (filterContext.IsChildAction)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt;;
        }
        &lt;span class="kwrd"&gt;if&lt;/span&gt;(DocumentSession != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (filterContext.Exception == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                DocumentSession.SaveChanges();
            }
            DocumentSession.Dispose();
        }
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnActionExecuted(filterContext);
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is all handled inside the base controller, and it is very similar to how I am doing that in my own apps.&lt;/p&gt;
&lt;p&gt;However, ScriptService and CandidateService seems strange, let us explore them a bit.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ScriptService
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IDocumentSession documentSession;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; ScriptService(IDocumentSession documentSession)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.documentSession = documentSession;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AttachScript(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber, Stream fileContents)
    {
        var metadata = &lt;span class="kwrd"&gt;new&lt;/span&gt; RavenJObject();
        documentSession.Advanced.DatabaseCommands.PutAttachment(versionNumber, &lt;span class="kwrd"&gt;null&lt;/span&gt;, fileContents, metadata);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; Stream GetScript(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber)
    {
        var attachment = documentSession.Advanced.DatabaseCommands.GetAttachment(versionNumber);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; attachment != &lt;span class="kwrd"&gt;null&lt;/span&gt; 
            ? attachment.Data() 
            : &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;So this is using RavenDB attachment to store stuff, I am not quite sure what yet, so let us track it down.&lt;/p&gt;
&lt;p&gt;This is being used like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[HttpGet]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult GetScript(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber)
{
    var candidate = CandidateService.FindOneByVersionNumber(versionNumber);
    var attachment = ScriptService.GetScript(versionNumber);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (attachment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        var result = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStreamResult(attachment, &lt;span class="str"&gt;"text/plain"&lt;/span&gt;);
        var version = candidate.VersionNumber;
        var product = candidate.ProductName;
        result.FileDownloadName = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"deploy-{0}-{1}.ps1"&lt;/span&gt;, product, version);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpNotFoundResult(&lt;span class="str"&gt;"Deployment script missing."&lt;/span&gt;);
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I am assuming that the scripts are deployment scripts for different versions, and that they get uploaded on every new release candidate.&lt;/p&gt;
&lt;p&gt;But look at the CandidateService, it looks like a traditional service wrapping RavenDB, and I have spoken against it multiple times.&lt;/p&gt;
&lt;p&gt;In particular, I dislike this bit of code:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ReleaseCandidate FindOneByVersionNumber(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber)
{
    var result = documentSession.Query&amp;lt;ReleaseCandidate&amp;gt;()
        .Where(x =&amp;gt; x.VersionNumber == versionNumber)
        .FirstOrDefault();
    &lt;span class="kwrd"&gt;if&lt;/span&gt;(result == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReleaseCandidateNotFoundException(versionNumber);
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Store(ReleaseCandidate candidate)
{
    var existing = documentSession.Query&amp;lt;ReleaseCandidate&amp;gt;()
        .Where(x =&amp;gt; x.VersionNumber == candidate.VersionNumber)
        .Any();
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (existing)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReleaseCandidateAlreadyExistsException(candidate.VersionNumber);
    }
    documentSession.Store(candidate);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;From looking at the code, it looks like the version number of the release candidate is the primary way to look it up. More than that, in the entire codebase, there is never a case where we load a document by id.&lt;/p&gt;
&lt;p&gt;When I see a VersionNumber, I think about things like “1.0.812.0”, but I think that in this case the version number is likely to include the product name as well, “RavenDB-1.0.812.0”, otherwise you couldn’t have two products with the same version.&lt;/p&gt;
&lt;p&gt;That said, the code above it wrong, because it doesn’t take into account RavenDB’s indexes BASE nature. Instead, the version number should actually be the ReleaseCandidate id. This way, because RavenDB’s document store is fully ACID, we don’t have to worry about index update times, and we can load things very efficiently.&lt;/p&gt;
&lt;p&gt;Pretty much all of the rest of the code in the CandidateService is only used in a single location, and I don’t really see a value in it being there.&lt;/p&gt;
&lt;p&gt;For example, let us look at this one:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[HttpPost]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult MarkAsDeployed(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber, &lt;span class="kwrd"&gt;string&lt;/span&gt; environment, &lt;span class="kwrd"&gt;bool&lt;/span&gt; success)
{
    CandidateService.MarkAsDeployed(versionNumber, environment, success);
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; EmptyResult();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_4.png" width="600" height="729"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, it is merely loading the appropriate release candidate, and calling the MarkAsDeployed method on it.&lt;/p&gt;
&lt;p&gt;Instead of doing this needless, forwarding, and assuming that we have the VersionNumber as the id, I would write:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[HttpPost]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult MarkAsDeployed(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber, &lt;span class="kwrd"&gt;string&lt;/span&gt; environment, &lt;span class="kwrd"&gt;bool&lt;/span&gt; success)
{
    var cadnidate = DocumentSession.Load&amp;lt;ReleaseCandidate&amp;gt;(versionNumber);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (cadnidate == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReleaseCandidateNotFoundException(versionNumber);
    var env = DocumentSession.Load&amp;lt;DeploymentEnvironment&amp;gt;(environment);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (env == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"Environment {0} not found"&lt;/span&gt;, environment));

    cadnidate.MarkAsDeployed(success, env);
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; EmptyResult();
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Finally, a word about the error handling, this is handled via:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnException(ExceptionContext filterContext)
{
    filterContext.Result = &lt;span class="kwrd"&gt;new&lt;/span&gt; ErrorResult(filterContext.Exception.Message);
    filterContext.ExceptionHandled = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ErrorResult : ActionResult
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; message;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; ErrorResult(&lt;span class="kwrd"&gt;string&lt;/span&gt; message)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.message = message;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.Write(message);
        context.HttpContext.Response.StatusCode = 500;
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;The crazy part is that OnException is overridden only on some of the controllers, rather than in the base controller, and even worse. This sort of code leads to error details loss.&lt;/p&gt;
&lt;p&gt;For example, let us say that I get a NullReferenceException. This code will dutifully tell me all about it, &lt;em&gt;but will not tell me where it happened&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This sort of thing make debugging &lt;em&gt;extremely&lt;/em&gt; hard.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AyendeRahien/~4/-b65I8jNg9I" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/AyendeRahien/~3/-b65I8jNg9I/reviewing-ravendb-app-releasecandidatetracker"&gt;Reviewing RavenDB app: ReleaseCandidateTracker&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/AyendeRahien"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bPCkCHIe-LOhY9MxjPVaHMfan2U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bPCkCHIe-LOhY9MxjPVaHMfan2U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bPCkCHIe-LOhY9MxjPVaHMfan2U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bPCkCHIe-LOhY9MxjPVaHMfan2U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 16 May 2012 13:00:00 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/AyendeRahien/~3/-b65I8jNg9I/reviewing-ravendb-app-releasecandidatetracker</guid>
    </item>
 
    <item>
      <title>Zen of python revisited with code samples</title>
      <author>Roy Osherove</author>
      <link>http://feedproxy.google.com/~r/Iserializable/~3/xeSN0EwTEVE/zen-of-python-revisited-with-code-samples.html</link>
      <description>&lt;p&gt;I really like &lt;a href="http://artifex.org/~hblanks/talks/2011/pep20_by_example.html"&gt;reading this code&lt;/a&gt;. I will look deeper into it this week.&lt;/p&gt;
&lt;p&gt;Many of the &amp;#8220;zen&amp;#8221; ideas here speak to me on the unit test level.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=xeSN0EwTEVE:sr_Sj8wSwPo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=xeSN0EwTEVE:sr_Sj8wSwPo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Iserializable?a=xeSN0EwTEVE:sr_Sj8wSwPo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Iserializable?i=xeSN0EwTEVE:sr_Sj8wSwPo:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Iserializable/~4/xeSN0EwTEVE" height="1" width="1"/&gt; &lt;hr /&gt;Read more: &lt;a href="http://feedproxy.google.com/~r/Iserializable/~3/xeSN0EwTEVE/zen-of-python-revisited-with-code-samples.html"&gt;Zen of python revisited with code samples&lt;/a&gt; | &lt;a href="http://feeds.feedburner.com/Iserializable"&gt;Subscribe&lt;/a&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kkKd5TK7PcIu41swC57138Mz7N8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kkKd5TK7PcIu41swC57138Mz7N8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kkKd5TK7PcIu41swC57138Mz7N8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kkKd5TK7PcIu41swC57138Mz7N8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 16 May 2012 01:14:45 GMT</pubDate>
      <guid>http://feedproxy.google.com/~r/Iserializable/~3/xeSN0EwTEVE/zen-of-python-revisited-with-code-samples.html</guid>
    </item>
 
  </channel>
</rss>

