<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" version="2.0">
    <channel>
        <title>K. Scott Allen</title>
        <link>http://odetocode.com/Blogs/scott/Default.aspx</link>
        <description>Experiments In Writing</description>
        <language>en-US</language>
        <copyright>K. Scott Allen</copyright>
        <generator>Subtext Version 2.2.0.0</generator>
        <image>
            <title>K. Scott Allen</title>
            <url>http://odetocode.com/Blogs/images/RSS2Image.gif</url>
            <link>http://odetocode.com/Blogs/scott/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/OdeToCode" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="odetocode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
            <title>Upcoming Events</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/02/08/upcoming-events.aspx</link>
            <description>&lt;p&gt;Here are some events I’ll be speaking at over the next couple months:&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.devteach.com/Index.aspx" target="_blank"&gt;DevTeach&lt;/a&gt; &lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;Toronto / Mississauga March 8-12&lt;/strong&gt;. DevTeach stands for Developers Teaching. It’s a conference done by developers for developers. This annual event offers the elements of an international conference and the elements of a community event. Sessions include both presentation material and, whenever possible, hands-on training. We like to describe this event as the Developers Festival. Find out who should attend at &lt;a href="http://www.devteach.com/WhoShouldAttend.aspx#Who"&gt;this link&lt;/a&gt;. Check out the &lt;a href="http://www.devteach.com/WhoShouldAttend.aspx"&gt;top ten ways&lt;/a&gt; to convince your boss to let you go this event. DevTeach is about becoming one of the best developer by getting training from the &lt;a href="http://www.devteach.com/Speaker.aspx"&gt;best in the industry&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.scandevconf.se/2010/conference/" target="_blank"&gt;Scandinavian Developer Conference&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;Göteborg, Sweden March 16-17&lt;/strong&gt;. Whether you are someone learning development in Java, .NET or IBM i or you are an experienced user of these technologies for 10 years or more, there are lot of great information to be shared with everyone.&lt;/p&gt;  &lt;p&gt;In addition to technical sessions, we will also have tracks with presentations about the Development Process and Methodology: Agile Methodology, Test Driven Development, System Engineering, Architecture, Project Management, Best practices, "Agile in the Organization". We will also have tracks about hot topics like Cloud Computing, Testing, Web Development and Mobile Solutions. At the Conference there will also be a track of Emerging Technologies presented in cooperation with ThoughtWorks ( &lt;a href="http://www.thoughtworks.com/"&gt;www.thoughtworks.com&lt;/a&gt; )&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.devdays.nl/Default.aspx?pid=68&amp;amp;lang=en" target="_blank"&gt;DevDays 2010&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;DevDays is being held at World Forum in Den Haag March 30-31.&lt;/strong&gt; DevDays 2010: the biggest Microsoft event in the Netherlands for software development and software architecture. Every year, thousands of professionals visit DevDays to get completely up-to-date with all recent developments in their area of expertise in two days.&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.devconnections.com/" target="_blank"&gt;DevConnections&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;Las Vegas April 12-14 2010. &lt;/strong&gt;Developers from around the world will gather at the world famous Bellagio, for the Microsoft Visual Studio Conference &amp;amp; Expo, ASP.NET &amp;amp; Silverlight Conference &amp;amp; Expo and SQL Server Conference &amp;amp; Expo. You can be a part of this exciting event while you enjoy one of the most stunning hotels on the Las Vegas Strip at a great conference rate!&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1047.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=1JaVYgjkngg:VxqtCJdzgS8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/02/08/upcoming-events.aspx</guid>
            <pubDate>Mon, 08 Feb 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/02/08/upcoming-events.aspx#feedback</comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1047.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1047.aspx</trackback:ping>
        </item>
        <item>
            <title>Thoughts on an MVVM Rant</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/02/02/thoughts-on-an-mvvm-rant.aspx</link>
            <description>&lt;p&gt;I stumbled across “&lt;a href="http://forums.silverlight.net/forums/p/159237/356897.aspx#356897"&gt;A vent abount MVVM Development&lt;/a&gt;” thanks to a tweet from @&lt;a href="http://twitter.com/peterbromberg"&gt;peterbromberg&lt;/a&gt;. Excerpt:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;What really irritates me is that I am forced to waste so much time on how to try and figure out how a complex User Interface will work together with a suitable "ViewModel" all for the sake of being more "testable".  I could cobble together a pretty darn good application and still be able to split up the work among User Interface and code-behind developers.  I think adopting a non-industry standard, seemingly "best practices" ideology just because it seems 'cool' and it's "there" is the wrong approach to application development&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/novembering/123651421/" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="MVVM Rockstar" border="0" alt="MVVM Rockstar" align="right" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/ThoughtsonanMVVMRant_143/rockstar_3.jpg" width="184" height="244" /&gt;&lt;/a&gt; Ah, MVVM! MVVM is the rock star who packs the house at every XAML event. It’s in books, blog posts, and podcasts. You can’t swing a dead laptop without hitting someone who is spouting about the virtues of model-view-viewmodel. With so much hype, there’s bound to be backlash. &lt;/p&gt;  &lt;p&gt;Does MVVM deserve the hype? &lt;/p&gt;  &lt;p&gt;Short answer – no.&lt;/p&gt;  &lt;h3&gt;An Alternative?&lt;/h3&gt;  &lt;p&gt;You’ve got a complex UI with lots of rules, and you reject the MVVM best practice crap the whiteboarding architect is jamming down your throat. You’re gonna be … &lt;strong&gt;pragmatic!&lt;/strong&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;SaveButton_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)
{
   &lt;span style="color: blue"&gt;if&lt;/span&gt;(ThisIsValid)
   {
       &lt;span style="color: blue"&gt;if &lt;/span&gt;(ThatIsValid)
       {
           IsDragging = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
        
           &lt;span style="color: blue"&gt;if &lt;/span&gt;(DraftCheckBox.IsChecked.HasValue &amp;amp;&amp;amp;
               DraftCheckBox.IsChecked == &lt;span style="color: blue"&gt;true &lt;/span&gt;&amp;amp;&amp;amp;
               ItemList.SelectedItem != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               DragDropTarget.Children.Clear();
               SaveSomethingToWebServiceAsDraft();
           }
           &lt;span style="color: blue"&gt;else
           &lt;/span&gt;{
               DoSomethingElse();
               EmptyAllControls();
           }
       }
   }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Managing a complex UI by jamming code into event handlers results in something spectacular – as does throwing a bucket of water on a raging grease fire. Afterwards the fundamental problem of complexity (or fire) still exists – and it’s even worse than before! &lt;/p&gt;

&lt;h3&gt;Doesn’t MVVM Take Care of Complexity?&lt;/h3&gt;

&lt;p&gt;I’d argue that MVVM doesn’t solve the complexity problem by itself. Neither does SOA or object databases or tomorrow's next big thing. They all help - but they don’t make complex requirements disappear. At some point you have to roll up your sleeves and work on a design that manages the complexity at an acceptable level for your team, your skill level, your business, and your environment. Experience plays a key role here because it’s all been done before. Breaking complex things into simple, composable pieces requires practice with abstraction techniques and knowing where to apply the right amount of encapsulation. &lt;/p&gt;

&lt;p&gt;One drawback to the MVVM hype is how the hype drives people to one solution for every problem. The truth is there are lots of tricks to managing a complex UI, and some of them are dead simple and have built-in tooling support. Here is a sample:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User controls and custom controls&lt;/li&gt;

  &lt;li&gt;Behaviors (underutilized, IMHO)&lt;/li&gt;

  &lt;li&gt;Triggers and visual states&lt;/li&gt;

  &lt;li&gt;Events and event aggregators&lt;/li&gt;
&lt;/ul&gt;

&lt;p /&gt;

&lt;p /&gt;

&lt;p&gt;The trick is to pick the right tool for the job.  &lt;/p&gt;

&lt;h3&gt;So What Can MVVM Do For Me?&lt;/h3&gt;

&lt;p&gt;I think MVVM &lt;em&gt;does &lt;/em&gt;help to manage complexity and and produce maintainable code. I’ve had success with MVVM. Like every separated presentation pattern it divides the varied concerns of a user interface. You can’t dismiss the MV* type patterns as pie in the sky architecture –they’ve served the industry well for decades. &lt;/p&gt;

&lt;p&gt;What makes MVVM different? Why is it shiny and new? I think it’s because MVVM’s raison d'être is data binding.  It’s easy to dismiss MVVM as just another UI pattern, but binding does give MVVM a slightly different flavor (a bit salty at times, but that’s just because of the static typing). If you’ve already been using a separated presentation pattern, it’s the data binding capabilities you need to understand and leverage. Data binding is quite powerful in WPF and Silverlight. You can perform amazing feats with little effort and without sacrificing encapsulation. Giving up on data binding is giving up on many of the advantages in the platform. &lt;/p&gt;

&lt;p&gt;Proper use of MVVM also gives you a testable chunk of code. I think it’s strange that the MVVM rant dismisses the work needed to make a complex UI testable. I’d think a complex UI would need more testing than a simple UI. &lt;/p&gt;

&lt;p&gt;On the other hand, I did just read “&lt;a href="http://arstechnica.com/business/news/2010/01/how-a-stray-mouse-click-choked-the-nyse-cost-a-bank-150k.ars" target="_blank"&gt;How a stray mouse click choked the NYSE &amp;amp; cost a bank $150K&lt;/a&gt;”, so I might not be thinking clearly.&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1045.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=xfpQR6076A4:Qx9wtD0-mlQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/02/02/thoughts-on-an-mvvm-rant.aspx</guid>
            <pubDate>Tue, 02 Feb 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/02/02/thoughts-on-an-mvvm-rant.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1045.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1045.aspx</trackback:ping>
        </item>
        <item>
            <title>Wrapping about Collections</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/31/wrapping-about-collections.aspx</link>
            <description>&lt;p&gt;Mark Needham’s “&lt;a href="http://www.markhneedham.com/blog/"&gt;Thoughts On Software Development&lt;/a&gt;” is a great collection of blog posts. Last year Mark wrote “&lt;a href="http://www.markhneedham.com/blog/2009/10/23/coding-the-primitive-obsession/"&gt;Coding: The primitive obsession&lt;/a&gt;”, and challenged the idea that the &lt;a href="http://grabbagoft.blogspot.com/2007/12/dealing-with-primitive-obsession.html"&gt;primitive obsession&lt;/a&gt; anti-pattern is just about overusing low level data types like string and int. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The most frequent offender seems to be the creation of collections of things which we then query to find specific items elsewhere in the code. More often that not we'll also perform some custom logic on that particular item.&lt;/p&gt;    &lt;p&gt;At its most extreme we might extract each of the items in a collection and make use of them separately. This somewhat defeats the purpose of the collection.&lt;/p&gt;    &lt;p&gt;When this happens it often seems to me that what we actually have is a series of attributes of an object rather than a collection.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Mark goes on to describe how wrapping a collection can often create a more useful abstraction, then points to his debate in &lt;a href="http://www.markhneedham.com/blog/2009/07/24/wrapping-collections-inheritance-vs-composition/"&gt;Wrapping collections: Inheritance vs Composition&lt;/a&gt;. It’s a good read. &lt;/p&gt;  &lt;p&gt;I’ve been wrapping collections a bit myself lately, and it’s not too hard to create a custom collection that is both feature rich and descriptive of the problem it solves using composition. For example, let’s say you need to keep a collection of Stamp objects and support INotifyCollectionChanged. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StampCollection &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt;, 
                               &lt;span style="color: #2b91af"&gt;INotifyCollectionChanged
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;StampCollection()
    {
        _items = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt;();
        _items.CollectionChanged += ItemsCollectionChanged;
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;AddStamp(&lt;span style="color: #2b91af"&gt;Stamp &lt;/span&gt;newStamp)
    {
        &lt;span style="color: green"&gt;/* logic */

        &lt;/span&gt;_items.Add(newStamp);
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;RemoveStamp(&lt;span style="color: #2b91af"&gt;Stamp &lt;/span&gt;stamp)
    {
        &lt;span style="color: green"&gt;/* logic */

        &lt;/span&gt;_items.Remove(stamp);
    }

    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt; GetEnumerator()
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_items.OrderBy(stamp =&amp;gt; stamp.Something)
                     .GetEnumerator();
    }

    &lt;span style="color: #2b91af"&gt;IEnumerator IEnumerable&lt;/span&gt;.GetEnumerator()
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;GetEnumerator();
    }

    &lt;span style="color: blue"&gt;public event &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotifyCollectionChangedEventHandler 
        &lt;/span&gt;CollectionChanged = &lt;span style="color: blue"&gt;delegate &lt;/span&gt;{ };

    &lt;span style="color: blue"&gt;void &lt;/span&gt;ItemsCollectionChanged(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, 
                                &lt;span style="color: #2b91af"&gt;NotifyCollectionChangedEventArgs &lt;/span&gt;e)
    {
        CollectionChanged(&lt;span style="color: blue"&gt;this&lt;/span&gt;, e);
    }

    &lt;span style="color: blue"&gt;readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt; _items;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Yes, it’s a bit of code, but it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Gives you complete control over the surface area of the API compared to inheriting from ObservableCollection&amp;lt;T&amp;gt; or List&amp;lt;T&amp;gt;&lt;/li&gt;

  &lt;li&gt;Allows precise control over adding and removing objects (validation, perhaps updating fields). &lt;/li&gt;

  &lt;li&gt;Becomes a more descriptive part of the domain&lt;/li&gt;

  &lt;li&gt;Is not to be confused with a &lt;a href="http://www.youtube.com/watch?v=3o_6qlmKW94"&gt;rap collection&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1044.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=8z7CxnaAkk0:KBrcJIyeWeU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/31/wrapping-about-collections.aspx</guid>
            <pubDate>Mon, 01 Feb 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/31/wrapping-about-collections.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1044.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1044.aspx</trackback:ping>
        </item>
        <item>
            <title>KISS Your ASP.NET MVC Routes</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/25/kiss-your-asp-net-mvc-routes.aspx</link>
            <description>&lt;p&gt;A little bit of thinking and compromise can remove unnecessary complexity from the routes in an MVC application. &lt;/p&gt;  &lt;p&gt;For example:&lt;/p&gt;  &lt;p&gt;Morgan’s web site has authenticated users,and Morgan decides the URLs for managing users should look like &lt;em&gt;/morgan/detail&lt;/em&gt;. Morgan adds the following code to register the route:&lt;/p&gt;  &lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;,
    &lt;span style="color: #a31515"&gt;"{username}/{action}"&lt;/span&gt;,
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller =&lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;, action=&lt;span style="color: #a31515"&gt;"Index" &lt;/span&gt;}
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Morgan runs some tests and it looks like there is a problem. The User controller is getting requests for &lt;em&gt;/home/index&lt;/em&gt;. Oops, that request should have gone to the Home controller. Fortunately, Morgan knows there is all sorts of whizz-bang features you can add to a route, so Morgan creates a route constraint: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserRouteConstraint &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IRouteConstraint
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;Match(&lt;span style="color: #2b91af"&gt;HttpContextBase &lt;/span&gt;httpContext, 
                      &lt;span style="color: #2b91af"&gt;Route &lt;/span&gt;route, &lt;span style="color: blue"&gt;string &lt;/span&gt;parameterName, 
                      &lt;span style="color: #2b91af"&gt;RouteValueDictionary &lt;/span&gt;values, 
                      &lt;span style="color: #2b91af"&gt;RouteDirection &lt;/span&gt;routeDirection)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;username = values[&lt;span style="color: #a31515"&gt;"username"&lt;/span&gt;] &lt;span style="color: blue"&gt;as string&lt;/span&gt;;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;IsCurrentUser(username);
    }

    &lt;span style="color: blue"&gt;private bool &lt;/span&gt;IsCurrentUser(&lt;span style="color: blue"&gt;string &lt;/span&gt;username)
    {
        &lt;span style="color: green"&gt;// ... look up the user
    &lt;/span&gt;}
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The constraint prevents the User route from gobbing requests to other controllers. It only allows requests to reach the User controller when the username exists in the application. &lt;/p&gt;

&lt;p&gt; Morgan tweaks the route registration code to include the constraint:&lt;/p&gt;

&lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;,
    &lt;span style="color: #a31515"&gt;"{username}/{action}"&lt;/span&gt;,
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller =&lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;, action=&lt;span style="color: #a31515"&gt;"Index"&lt;/span&gt;},
&lt;strong&gt;    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ user = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserRouteConstraint&lt;/span&gt;()&lt;/strong&gt; }
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Morgan runs some tests and everything works!&lt;/p&gt;

&lt;p&gt;Well …&lt;/p&gt;

&lt;p&gt;Everything works until a user registers with the name “home”. Morgan goes off to tweak the code again...&lt;/p&gt;

&lt;h3&gt;STOP!&lt;/h3&gt;

&lt;p&gt;As a rule of thumb I try to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Never use advanced routing features like constraints&lt;/li&gt;

  &lt;li&gt;Always stick to a URL like {controller}/{action}/{id} or {controller}/{id}/{action}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes you have to go break those rules, but let’s look at Morgan’s case. If Morgan was happy with a URL like /user/index/morgan, then Morgan wouldn’t need to register any additional routes. The default routing entry in a new MVC application would happily invoke the index action of the User controller and pass along the username as the id parameter. Morgan could also go with /user/morgan and use a simple route entry like this:&lt;/p&gt;

&lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;,
    &lt;span style="color: #a31515"&gt;"User/{username}/{action}"&lt;/span&gt;,
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller =&lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;, action=&lt;span style="color: #a31515"&gt;"Index"&lt;/span&gt;, username=&lt;span style="color: #a31515"&gt;"*"&lt;/span&gt;}
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;No constraints required! &lt;/p&gt;

&lt;p&gt;The KISS principle (&lt;em&gt;keep it simple stupid&lt;/em&gt;) is a good design principle for routes. You’ll have fewer moving parts, consistent URL structures, and make the code easier to maintain.&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1043.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=rZcV0nGx1T0:6oZis3B6bI0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/25/kiss-your-asp-net-mvc-routes.aspx</guid>
            <pubDate>Mon, 25 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/25/kiss-your-asp-net-mvc-routes.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1043.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1043.aspx</trackback:ping>
        </item>
        <item>
            <title>Silverlight and ASP.NET MVC Don&amp;rsquo;t Serve the Same Master</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/18/silverlight-and-asp-net-mvc-donrsquot-serve-the-same-master.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/pulihora/255322178/" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="contrast" border="0" alt="contrast" align="right" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/Silverlight.NETMVCDontServetheSameMaster_1294B/contrast_3.jpg" width="244" height="164" /&gt;&lt;/a&gt; I’m flipping between MVC and Silverlight projects when a startling contrast starts to emerge. It’s not the obvious contrast between stateful and stateless. It’s a subtler contrast in design. &lt;/p&gt;  &lt;p&gt;If you poke around in a new MVC project, one of the first pieces of code you’ll run across is the code to register the default route. It’s in global.asax.cs, and looks like this:&lt;/p&gt;  &lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"Default"&lt;/span&gt;,                                            
    &lt;span style="color: #a31515"&gt;"{controller}/{action}/{id}"&lt;/span&gt;,                         
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller = &lt;span style="color: #a31515"&gt;"Home"&lt;/span&gt;, action = &lt;span style="color: #a31515"&gt;"Index"&lt;/span&gt;, id = &lt;span style="color: #a31515"&gt;"" &lt;/span&gt;}
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This snippet relies on some of the recent features added to C# – extension methods and anonymously typed objects. It obviously draws some inspiration from &lt;a href="http://guides.rubyonrails.org/routing.html"&gt;Ruby on Rails&lt;/a&gt;, which builds on top of the dynamic, malleable Ruby language. &lt;/p&gt;

&lt;p&gt;Compare that code to the code you’ll see when you open up just about any Silverlight control.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/Silverlight.NETMVCDontServetheSameMaster_1294B/silverlight_2.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="silverlight code" border="0" alt="silverlight code" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/Silverlight.NETMVCDontServetheSameMaster_1294B/silverlight_thumb.png" width="202" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Well, you don’t actually see much code because the code is swept underneath a carpet of regions. This happens quite often in Silverlight, and I think it’s because developers are embarrassed to write lines and lines and lines of code to define a single simple property. It’s the elegance of RPG combined with the verbosity of COBOL. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsDropDownOpen
{
    &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: blue"&gt;bool&lt;/span&gt;)GetValue(IsDropDownOpenProperty); }
    &lt;span style="color: blue"&gt;set &lt;/span&gt;{ SetValue(IsDropDownOpenProperty, &lt;span style="color: blue"&gt;value&lt;/span&gt;); }
}

&lt;span style="color: blue"&gt;public static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyProperty &lt;/span&gt;IsDropDownOpenProperty =
    &lt;span style="color: #2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(
        &lt;span style="color: #a31515"&gt;"IsDropDownOpen"&lt;/span&gt;,
        &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;bool&lt;/span&gt;),
        &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Foo&lt;/span&gt;),
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PropertyMetadata&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;, OnIsDropDownOpenPropertyChanged));&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;I realize IsDropDownOpen isn’t &lt;em&gt;just&lt;/em&gt; a simple property. It’s a dependency property, and dependency properties hold many great and magical powers. Data binding in Silverlight (and WPF), for example, is wonderfully feature rich and easy, but it comes with a price.&lt;strong&gt; Instead of writing one line of code …&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsDropDownOpen { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;… &lt;strong&gt;we need twelve!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The contrast isn’t in the number of lines of code, however. The contrast is in &lt;em&gt;who&lt;/em&gt; the frameworks were designed to serve. &lt;/p&gt;

&lt;h3&gt;MVC is for Developers – Silverlight is for Tools&lt;/h3&gt;

&lt;p&gt;The MVC framework is designed for developers who write code. This fact is obvious in the API design and how the team fights for programmer friendly features like the new &lt;a href="http://haacked.com/archive/2009/09/25/html-encoding-code-nuggets.aspx" target="_blank"&gt;HTML encoding block syntax&lt;/a&gt;. The MapRoute code we saw earlier is just one example of many. The MVC framework took inspiration from platforms that are popular today because they favor &lt;a href="http://en.wikipedia.org/wiki/Convention_over_configuration" target="_blank"&gt;convention over configuration&lt;/a&gt; and &lt;a href="http://blog.thinkrelevance.com/2008/4/1/ending-legacy-code-in-our-lifetime" target="_blank"&gt;essence over ceremony&lt;/a&gt;. These are fancy terms for keeping things &lt;strong&gt;simple and readable&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Silverlight is designed for tooling. Visual Studio, Expression Blend, and other XAML, code, and art editors. I’m not saying we get rid of the tools. We &lt;em&gt;need&lt;/em&gt; the tools for the feedback and capabilities they provide when building effects, animations, and irregularly shaped objects. But, it seems the developer’s life gets more difficult with the addition of every feature.&lt;/p&gt;

&lt;h3&gt;The Next 5 Years&lt;/h3&gt;

&lt;p&gt; I’d be surprised if another language doesn’t come along to become the de facto standard for the code behind XAML files. A language that is just as friendly to programmers as it is to XAML. A language that makes writing code for System.Windows fun, simple, and readable.  Maybe it will look like … &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;depprop bool &lt;/span&gt;IsDropDownOpen { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;… but smarter people then me can figure out the syntax. I just know there has to be something better. &lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1042.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=sYc4wnE9Dco:H6kgdILji1k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/18/silverlight-and-asp-net-mvc-donrsquot-serve-the-same-master.aspx</guid>
            <pubDate>Tue, 19 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/18/silverlight-and-asp-net-mvc-donrsquot-serve-the-same-master.aspx#feedback</comments>
            <slash:comments>12</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1042.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1042.aspx</trackback:ping>
        </item>
        <item>
            <title>Drop-down Lists and ASP.NET MVC</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx</link>
            <description>&lt;p&gt;Working with drop-down lists in ASP.NET MVC has some confusing aspects, so let’s look at an example. &lt;/p&gt;  &lt;p&gt;Imagine the goal is to edit a song (not the music and lyrics of a song – just the boring data pieces). Each song is associated with an album, and each song has a title and track number. With this description, you can imagine an edit view using the following code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.DropDownList(&lt;span style="color: #a31515"&gt;"AlbumId"&lt;/span&gt;, Model.Albums)&lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;  ...
&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: #a31515"&gt;"Title"&lt;/span&gt;, Model.Title) &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;   ...
&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: #a31515"&gt;"TrackNumber"&lt;/span&gt;, Model.TrackNumber) &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The Html.DropDownList helper method likes to work with SelectListItem objects, so a view model you can pair with this view looks like the following:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EditSongViewModel
&lt;/span&gt;{        
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Title { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }                
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;TrackNumber { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;&amp;gt; Albums { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Some people don’t like to use SelectListItem types in their view models. Instead, they’ll convert to them in the view. I think it’s entirely reasonable to use SelectListItem in a view model, because the view model is supposed to make the view easier to write. Having the view model perfectly aligned with the needs of the view means you need to think less (and write less code) when creating the view. &lt;/p&gt;

&lt;h3&gt;Creating SelectListItems&lt;/h3&gt;

&lt;p&gt;There are a couple approaches you can take when creating a sequence of SelectListItem objects. I think the cleanest approach is to have an extension method that knows how to take a collection of objects in your software (like Album objects), and map them into SelectListItem objects. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;&amp;gt; ToSelectListItems(
              &lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Album&lt;/span&gt;&amp;gt; albums, &lt;span style="color: blue"&gt;int &lt;/span&gt;selectedId)
{
    &lt;span style="color: blue"&gt;return 
        &lt;/span&gt;albums.OrderBy(album =&amp;gt; album.Name)
              .Select(album =&amp;gt; 
                  &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem
                  &lt;/span&gt;{
                    Selected = (album.ID == selectedId),
                    Text = album.Name,
                    Value = album.ID.ToString()
                   });
}&lt;/pre&gt;

&lt;p&gt;You can use the method like this:&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = _repository.FindAllAlbums().ToSelectItems(selectedId);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That code works, because Html.DropDownList will happily work with IEnumerable of SelectListItem. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The class you need to be careful with is the SelectList class.&lt;/strong&gt; I’ve seen quite a few people make the mistake of wrapping their SelectListItem objects in a SelectList without setting the DataTextField and DataValueField properties. This does &lt;strong&gt;not&lt;/strong&gt; work:&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectList&lt;/span&gt;(
                _repository.FindAllAlbums().ToSelectListItems(1)
                );&lt;/pre&gt;

&lt;p&gt;You’d think the SelectList class would know how to work with a collection of SelectListItem objects - but it doesn’t. The following doesn’t work either (the drop-down list will display “System.Web.Mvc.SelectListItem” for every entry):&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = 
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectList&lt;/span&gt;(_repository.FindAllAlbums()
                              .ToSelectItems(selectedID));&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The SelectList class is really designed to perform the conversion we did earlier (with the extension method), but it uses late binding reflection. The following &lt;strong&gt;would&lt;/strong&gt; work, because we tell the SelectList where to find the text and value fields:&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectList&lt;/span&gt;(
                _repository.FindAllAlbums(), &lt;span style="color: #a31515"&gt;"ID"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Name"
                &lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;h3&gt;Reading the Selection&lt;/h3&gt;

&lt;p&gt;If you are using the same model to accept input from the edit view during a postback, you might think the default model binder will repopulate the Albums collection with all the album information and set the selected album. Unfortunately - the web doesn’t work this way and the Albums collection will be empty. &lt;/p&gt;

&lt;p&gt;The only album related information the browser will post is the value of the selected item. If you want this value bound to a model, you’ll need to provide an AlbumId property (to match the name we gave the DropDownList in the view - “AlbumId”). &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EditSongViewModel
&lt;/span&gt;{
&lt;strong&gt;    &lt;span style="color: blue"&gt;public int &lt;/span&gt;AlbumId { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
&lt;/strong&gt;    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Title { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }                
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;TrackNumber { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;&amp;gt; Albums { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Some people will create two separate view models in this case. One view model is designed to carry information to the view, and will have an Albums property (but no AlbumId property). The second view model is designed to accept user input during postback and will have an AlbumId propery (but no Albums property). This approach adds the overhead of an extra class, but the view models are perfectly aligned with their duties and no properties go unused. You’ll have to decide which approach is best for you. &lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Don’t use a SelectList without telling it the DataTextField and DataValueField properties to use.&lt;/li&gt;

  &lt;li&gt;Don’t expect to see a collection for a drop-down list repopulated on a postback.&lt;/li&gt;

  &lt;li&gt;Extension methods make it easy to create a sequence of SelectListItem objects in strongly-typed code.&lt;/li&gt;

  &lt;li&gt;Html.DropDownList doesn’t &lt;em&gt;require&lt;/em&gt; a SelectList – it’s happy working with any sequence of SelectListItem objects. &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1041.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=2DeSSGTZV9M:Tp4pYNBJQ9c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx</guid>
            <pubDate>Mon, 18 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx#feedback</comments>
            <slash:comments>15</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1041.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1041.aspx</trackback:ping>
        </item>
        <item>
            <title>T4MVC in MSDN Magazine</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/13/t4mvc-in-msdn-magazine.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/ee291528.aspx"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="msdn january 2010" border="0" alt="msdn january 2010" align="right" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/T4TemplatesforMVCinMSDNMagazine_139EE/msdn_3.jpg" width="188" height="243" /&gt;&lt;/a&gt; The &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee291528.aspx"&gt;January 2010 issue of MSDN Magazine&lt;/a&gt; is online with my article covering T4MVC:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: 16px 'Times New Roman'; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"&gt;&lt;span style="line-height: 18px; font-family: 'Segoe UI', verdana, arial; color: rgb(51,51,51); font-size: 14px" class="Apple-style-span"&gt;Microsoft Visual Studio includes a code generation engine known as T4 (which is short for Text Template Transformation Toolkit). You’ve probably already used T4 templates in Visual Studio without even knowing they were working behind the scenes. In this article I’m going to give you a basic introduction to T4 templates and show you how ASP.NET MVC uses this technology. I’ll also show you how to customize T4 templates to enhance your day-to-day work with the MVC framework&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Thanks go to &lt;a href="http://blogs.msdn.com/davidebb/default.aspx"&gt;David Ebbo&lt;/a&gt; for his help and comments on the article. David continues to improve  T4MVC, for example: &lt;a href="http://blogs.msdn.com/davidebb/archive/2010/01/04/t4mvc-2-6-10-fluent-route-value-api-shorter-way-to-refer-to-action-and-more.aspx"&gt;T4MVC 2.6.10: fluent route value API, shorter way to refer to action, and more&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1040.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=GgMW1T27TeA:rcY5yxnwvN4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/13/t4mvc-in-msdn-magazine.aspx</guid>
            <pubDate>Thu, 14 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/13/t4mvc-in-msdn-magazine.aspx#feedback</comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1040.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1040.aspx</trackback:ping>
        </item>
        <item>
            <title>Of Web Browsers and Humanity</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/13/of-web-browsers-and-humanity.aspx</link>
            <description>&lt;p&gt;Douglas Crockford posted an interesting topic for discussion on &lt;a href="http://www.crockford.com/" target="_blank"&gt;his site&lt;/a&gt; (look for the &lt;em&gt;Discussion Topic&lt;/em&gt; section at the bottom of the page):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;If a web browser is defective, causing errors in the display or performance of the page, should the page developer struggle to hide the browser's defects, or should the defects be revealed in hope of creating market pressure to force the browser maker to make good? By which approach is humanity better served?&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;What I’d Like To Say&lt;/h3&gt;  &lt;p&gt;When I was a kid, I loved &lt;a href="http://en.wikipedia.org/wiki/Mad_libs" target="_blank"&gt;Mad Libs&lt;/a&gt;. And I bet you could come up with a Mad Lib that represents a style of question every web developer asks on a regular basis. I think it would look like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I’m trying to ______ a ______ and it’s fine in ______ and _______, but in ______ it doesn’t _______ing work. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s always the same question - you just have to fill in the blanks with 1 CSS property, 1 DOM element, 3 browser versions, and one profanity. Isn’t it insane? Can’t we start a revolution and all make a New Year’s resolution?&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="This year I will not write hacky workaround code for defective browsers" border="0" alt="This year I will not write hacky workaround code for defective browsers" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/cc3e09f16d3c_AE0/resolution_3.jpg" width="304" height="204" /&gt;&lt;/p&gt;  &lt;h3&gt;But …&lt;/h3&gt;  &lt;p&gt;It’s a business decision. I think this is what gets under the collective skin of the web development community more than anything else. We can’t make a resolution to stop! We already told the bosses they’ll spend an extra $10,000 to support &lt;a href="http://www.positioniseverything.net/explorer.html" target="_blank"&gt;IE6&lt;/a&gt;, but they are more than happy with the &lt;em&gt;return on the investment.&lt;/em&gt; So, we sulk back to our offices and grudgingly add some more conditional CSS comments to the site’s style sheet. &lt;/p&gt;  &lt;p&gt;If there is going to be market pressure, it won’t come from developers per se, but from big Internet properties with fanatical followers, like Facebook, Amazon, eBay, and Twitter. They have the power to force users to move, and when users start moving the makers react. &lt;/p&gt;  &lt;p&gt;And yes, I think it is in the best interest of humanity.&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1039.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=OSzZvgDU7F0:9F0UXB274Ns:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/13/of-web-browsers-and-humanity.aspx</guid>
            <pubDate>Wed, 13 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/13/of-web-browsers-and-humanity.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1039.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1039.aspx</trackback:ping>
        </item>
        <item>
            <title>Don&amp;rsquo;t Let Your Code Marry An Axe Murderer</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/12/donrsquot-let-your-code-marry-an-axe-murder.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/KnowingWhatToAvoidIsOneKeyToSuccess_15073/axe_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="272/365" border="0" alt="272/365" align="right" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/KnowingWhatToAvoidIsOneKeyToSuccess_15073/axe_thumb.jpg" width="304" height="204" /&gt;&lt;/a&gt; It’s a lesson I learned from the school of hard knocks: be careful about the shady characters you let into your software. &lt;/p&gt;  &lt;p&gt;There are lots of software frameworks, components, and tools in the world – and they all want you to think you can live with them happily ever after. They seduce you with the promise of productivity, then hack you to death once they’ve gained your trust. &lt;/p&gt;  &lt;p&gt;Here are a few questions I’ve learned to ask when trying to spot next year’s problems:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1. How easy is it to deploy?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’ve been burned by software that is difficult to move from one environment to the next. Some products, particularly server products, assume you never need to move software into different environments (like development, test, productions). Avoid anything you can’t automate!&lt;/p&gt;  &lt;p&gt;Software should be as easy to deploy as possible, otherwise it doesn’t get deployed often enough. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2. Will it work in source control?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Some tools and designers generate files that don’t work well under source control. If you can’t diff and merge you lose a tremendous amount of flexibility when it comes time to branch, patch, and support concurrent development. Database tools are historically notorious for having problems in this area because they tend to design for DBAs instead of developers. &lt;/p&gt;  &lt;p&gt;It is, however, perfectly reasonable to &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2006/10/04/Check-in-all-your-binary-dependencies-into-Source-Control.aspx" target="_blank"&gt;check in binary dependencies&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3. Is it needy?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Speaking of dependencies – they are a &lt;a href="http://www.codinghorror.com/blog/archives/000497.html" target="_blank"&gt;touchy subject&lt;/a&gt;. You can’t invoke the “&lt;a href="http://www.codinghorror.com/blog/archives/000497.html" target="_blank"&gt;not invented here&lt;/a&gt;” rule in every decision without writing your own compiler. At the same time, every dependency you introduce to a product is a calculated risk. How many dependencies does this new thing have? Will you ever delay shipping because you are waiting for a new version of a dependency? Will you ever delay shipping because you are waiting for a new version of a dependency’s dependency? How many things will break when the next version arrives? Are you willing to run beta code, or code from the trunk? The answer is different for every application and business. &lt;/p&gt;  &lt;p&gt;In the end you need to make a decision from the gut, which means research into the history and pedigree of a dependency might be required. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4. When will it be obsolete?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you implement the solution to a problem in a mainstream programming language like C#, you can be reasonably sure it will still work and compile in 5 -10 years, even with new versions of the compiler. But, if you implement the same solution with Data Transformation Services (wait, &lt;a href="http://odetocode.com/blogs/scott/archive/2007/04/12/dts-in-sql-2005-good-news-and-bad-news.aspx" target="_blank"&gt;that’s obsolete&lt;/a&gt;), or Notification Services (wait, &lt;a href="http://sqlblog.com/blogs/greg_low/archive/2008/02/24/notification-services-isn-t-deprecated-in-sql-2k8-it-s-gone.aspx" target="_blank"&gt;that disappeared&lt;/a&gt;), or SQL Distributed Management Objects (oops, &lt;a href="http://msdn.microsoft.com/en-us/library/ms131540.aspx" target="_blank"&gt;it’s only a matter of time&lt;/a&gt;) - then you got some rewritin’ to do! &lt;/p&gt;  &lt;p&gt;Remember – nothing lasts forever … unless you have all the source code. &lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1038.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=MIUjc90dPRo:uAe0aVSuojM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=MIUjc90dPRo:uAe0aVSuojM:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=MIUjc90dPRo:uAe0aVSuojM:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=MIUjc90dPRo:uAe0aVSuojM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=MIUjc90dPRo:uAe0aVSuojM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=MIUjc90dPRo:uAe0aVSuojM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/12/donrsquot-let-your-code-marry-an-axe-murder.aspx</guid>
            <pubDate>Tue, 12 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/12/donrsquot-let-your-code-marry-an-axe-murder.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1038.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1038.aspx</trackback:ping>
        </item>
        <item>
            <title>More On The Death of If-Else</title>
            <link>http://odetocode.com/Blogs/scott/archive/2009/12/06/more-on-the-death-of-if-else.aspx</link>
            <description>&lt;p&gt;Aaron Feng posted recently on “&lt;a href="http://leftrightfold.com/?p=85"&gt;The death of if-else, if, and else&lt;/a&gt;”. In the post Aaron rewrote some JavaScript conditional checks using a &lt;a href="http://hop.perl.plover.com/book/pdf/02DispatchTables.pdf" target="_blank"&gt;dispatch table&lt;/a&gt; type approach. &lt;/p&gt;  &lt;p&gt;Following along with Aaron’s post using C#, we’d start with a list of Channel objects: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;channels = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Channel&lt;/span&gt;&amp;gt;
{
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Channel &lt;/span&gt;{ Number = 2,
                  Station = &lt;span style="color: #a31515"&gt;"NBC"&lt;/span&gt;,
                  ShowTitle = &lt;span style="color: #a31515"&gt;"Saturday Night Live"&lt;/span&gt;,
                  Genre = &lt;span style="color: #a31515"&gt;"comedy"&lt;/span&gt;,
                  Repeat = &lt;span style="color: blue"&gt;true &lt;/span&gt;},
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Channel &lt;/span&gt;{ Number = 3,
                  Station = &lt;span style="color: #a31515"&gt;"ESPN"&lt;/span&gt;,
                  ShowTitle = &lt;span style="color: #a31515"&gt;"College Football"&lt;/span&gt;,
                  Genre = &lt;span style="color: #a31515"&gt;"football"&lt;/span&gt;,
                  Repeat = &lt;span style="color: blue"&gt;false&lt;/span&gt;}
    &lt;span style="color: green"&gt;// ...
&lt;/span&gt;};&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Then we have the logic for deciding which channels to record:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;Surf(&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Channel&lt;/span&gt;&amp;gt; channels)
{
    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;channel &lt;span style="color: blue"&gt;in &lt;/span&gt;channels)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(channel.Genre == &lt;span style="color: #a31515"&gt;"football"&lt;/span&gt;)
        {
            Record(channel);
        }
        &lt;span style="color: blue"&gt;else if &lt;/span&gt;(channel.Genre == &lt;span style="color: #a31515"&gt;"comedy" &lt;/span&gt;&amp;amp;&amp;amp; 
                 !channel.Repeat)
        {
            Record(channel);
        }
        &lt;span style="color: blue"&gt;else if &lt;/span&gt;(channel.Genre == &lt;span style="color: #a31515"&gt;"crime" &lt;/span&gt;&amp;amp;&amp;amp;
                channel.ShowTitle != &lt;span style="color: #a31515"&gt;"Cops!"&lt;/span&gt;)
        {
            Record(channel);
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p /&gt;

&lt;p&gt;Rewriting the code using Aaron’s final approach would look like the following: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;Surf2(&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Channel&lt;/span&gt;&amp;gt; channels)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dispatch = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Channel&lt;/span&gt;&amp;gt;&amp;gt;
    {
        { &lt;span style="color: #a31515"&gt;"football"&lt;/span&gt;, c =&amp;gt; Record(c) },
        { &lt;span style="color: #a31515"&gt;"comedy"&lt;/span&gt;,   c =&amp;gt; {&lt;span style="color: blue"&gt;if&lt;/span&gt;(!c.Repeat) Record(c);}},
        { &lt;span style="color: #a31515"&gt;"crime"&lt;/span&gt;,    c =&amp;gt; {&lt;span style="color: blue"&gt;if&lt;/span&gt;(c.ShowTitle != &lt;span style="color: #a31515"&gt;"Cops!"&lt;/span&gt;) Record(c);}}
    };

    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;channel &lt;span style="color: blue"&gt;in &lt;/span&gt;channels)
    {
        dispatch[channel.Genre](channel);
    }
}&lt;/pre&gt;

&lt;p&gt;Personally, I feel Aaron’s dispatch table is not a big improvement over the previous “if else” version. The actions in the dispatch table are too busy. I think a cleaner approach is to just extract the rules into a data structure – essentially build a collections of predicates to evaluate. Given a channel, the data structure can tell me if the channel should be recorded. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;Surf3(&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Channel&lt;/span&gt;&amp;gt; channels)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;recordingRules = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Channel&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;[]
    {
        c =&amp;gt; c.Genre == &lt;span style="color: #a31515"&gt;"football"&lt;/span&gt;,
        c =&amp;gt; c.Genre == &lt;span style="color: #a31515"&gt;"comedy" &lt;/span&gt;&amp;amp;&amp;amp; !c.Repeat,
        c =&amp;gt; c.Genre == &lt;span style="color: #a31515"&gt;"crime" &lt;/span&gt;&amp;amp;&amp;amp; c.ShowTitle != &lt;span style="color: #a31515"&gt;"Cops!"
    &lt;/span&gt;};

    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;channel &lt;span style="color: blue"&gt;in &lt;/span&gt;channels)
    {
        &lt;span style="color: blue"&gt;if&lt;/span&gt;(recordingRules.Any(rule =&amp;gt; rule(channel) == &lt;span style="color: blue"&gt;true&lt;/span&gt;))
        {
            Record(channel);
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Not quite as flexible, but for this specific example its easier to read and maintain.&lt;/p&gt;

&lt;p&gt;What do you think? Is that better or worse?&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1037.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3WTlJ0ZWTxU:kfwogQvl_jk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3WTlJ0ZWTxU:kfwogQvl_jk:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3WTlJ0ZWTxU:kfwogQvl_jk:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3WTlJ0ZWTxU:kfwogQvl_jk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=3WTlJ0ZWTxU:kfwogQvl_jk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3WTlJ0ZWTxU:kfwogQvl_jk:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2009/12/06/more-on-the-death-of-if-else.aspx</guid>
            <pubDate>Mon, 07 Dec 2009 02:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2009/12/06/more-on-the-death-of-if-else.aspx#feedback</comments>
            <slash:comments>20</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1037.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1037.aspx</trackback:ping>
        </item>
    </channel>
</rss>
