<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0"><channel><title>Steve Smith's Blog</title><link>http://stevesmithblog.com/</link><description>Musings on Software and the Developer Community</description><generator>Graffiti CMS 1.2 (build 1.2.0.2308)</generator><lastBuildDate>Thu, 09 Jul 2009 14:57:49 GMT</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/StevenSmith" type="application/rss+xml" /><item><title>Principle of Least Surprise</title><link>http://stevesmithblog.com/blog/principle-of-least-surprise/</link><pubDate>Thu, 09 Jul 2009 14:57:49 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/principle-of-least-surprise/</guid><dc:creator>ssmith</dc:creator><slash:comments>2</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&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="surprise_thumb" border="0" alt="surprise_thumb" align="right" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/PrincipleofLeastSurprise_9A12/surprise_thumb_3.jpg" width="196" height="198" /&gt; When developing software, and especially when building user interfaces, it’s a good idea not to surprise the end user.&amp;#160; This is known as the &lt;a href="http://en.wikipedia.org/wiki/Principle_of_least_astonishment"&gt;Principle of Least Surprise&lt;/a&gt; (or Astonishment if you want to go for maximum drama).&amp;#160; It may seem obvious, but in practice it’s often easier said than done.&amp;#160; This is why user interfaces are often difficult to work with, especially if they’re built according to how the programmers think about the system with no input from actual users.&lt;/p&gt;  &lt;p&gt;For example, in a data entry scenario where some data entered could cause an inconsistency with other data in the system, there are several options one might consider.&amp;#160; To make this more concrete, let’s say that you can have an ad campaign spanning some time period, and within this you have individual advertisements, each with its own time period.&amp;#160; There is an overall business rule that the campaign time period defines the ultimate boundaries of the advertisements’ periods (start and end dates).&lt;/p&gt;  &lt;p&gt;Now, on form where the user can edit the campaign’s dates, you have to decide what to do if they change a date such that advertisements’ dates are now out of bounds.&amp;#160; For example, the campaign’s start date was 15 July 09 and its end date was 15 August 09, and within it is an advertisement &lt;strong&gt;A&lt;/strong&gt; that runs from 15 July 09 to 15 August 09 and another advertisement &lt;strong&gt;B&lt;/strong&gt; that runs from 20 July 09 to 27 July 09.&amp;#160; The user needs to update the campaign so that it starts on 16 July 09.&lt;/p&gt;  &lt;p&gt;Some options:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Always set all advertisements’ dates to the new campaign dates&lt;/li&gt;    &lt;li&gt;Throw a validation error and do not allow the user to save dates that would cause the advertisements’ dates to be invalid&lt;/li&gt;    &lt;li&gt;Warn the user that advertisement dates are now out of range, and let them click a button to adjust them to be the new campaign dates.&lt;/li&gt;    &lt;li&gt;Do nothing – let the new dates be set.&lt;/li&gt;    &lt;li&gt;Allow the update to go through but set a status flag on the campaign to show that it is now in an invalid state (and hope the user corrects this)&lt;/li&gt;    &lt;li&gt;Same as 5, but the update isn’t actually saved, but rather the campaign and advertisements are saved to a sandbox while their state is invalid, and the user is made aware that until the business rules are met, the whole campaign cannot be saved.&amp;#160; The user can continue editing the sandboxed version of the campaign and its advertisements until the dates meet the criteria, and then the whole batch can be saved as one transactional unit of work.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;There are certainly other options as well, but these are a good start for analysis purposes.&lt;/p&gt;  &lt;p&gt;The first option is the simplest, and ensures that no invalid state can exist from changing campaign dates, because the advertisement dates will always be reset to match the campaign dates.&amp;#160; However, unless the user expects this to be the behavior, they’re very likely going to be surprised to find out that when they thought they were editing campaign settings they were in fact editing all of the advertisements’ settings as well.&amp;#160; And in this case, advertisement B which clearly was meant to run for a particular 7-day period within the campaign will now have its date range reset to match the full campaign length, which is almost certainly not what the user expects.&lt;/p&gt;  &lt;p&gt;Option 2 is good from a PoLS standpoint, because the system doesn’t do anything that the user wasn’t expecting.&amp;#160; Unfortunately, the system doesn’t do anything useful, either.&amp;#160; If the user really wants to reset the campaign dates, they’re going to be stumped as to how to do it, and eventually might figure out that they need to edit each individual advertisement’s start date before they’ll be allowed to edit the campaign’s start date.&amp;#160; Hardly a good user experience, but at least the system has protected them from causing the system to enter an invalid state.&lt;/p&gt;  &lt;p&gt;Option 3 is excellent from a PoLS standpoint, because it informs the user of the possible issue but still lets the user accomplish the task they’ve set out to do.&amp;#160; And it offers the them a time-saving option to set the dates on the advertisements to match the campaign, which is probably often what the user wants to do, but unlike in option 1 this behavior is now explicit and thus will not come as a surprise to the user or occur when they don’t wish it to.&lt;/p&gt;  &lt;p&gt;Option 4 doesn’t immediately surprise the user, but is really one of the worst options because of its insidious nature.&amp;#160; Allowing the data to become inconsistent will surprise the user at a later date if they were expecting the system to ensure that the business rules were being maintained.&amp;#160; At some future date, when it’s discovered that the dates of the advertisements fall outside the dates of the campaign, and some unexpected system behavior results, the user is going to be puzzled as to how this could have been allowed to happen.&amp;#160; PoLS failure.&lt;/p&gt;  &lt;p&gt;Option 5 alone is quite reasonable from a PoLS standpoint, but could still allow inconsistent data to be saved into the production system, with the same ultimate consequences as Option 4.&lt;/p&gt;  &lt;p&gt;Option 6 seems like the best solution.&amp;#160; The user is made aware of the issues but is allowed to continue to make changes to the whole system (campaign + advertisements in this case) until they are in a consistent, valid state.&amp;#160; Only then can the changes be committed to the production data store.&amp;#160; This is an example of the &lt;a href="http://www.martinfowler.com/eaaCatalog/unitOfWork.html"&gt;Unit of Work pattern&lt;/a&gt;, and unlike most web-based applications that commit work with each request, this might require the transaction to be maintained across multiple requests before ultimately being committed to the database.&amp;#160; No magic happens behind the scenes that the user didn’t expect, and no future consequences occur that the user doesn’t expect, either.&amp;#160; And, bonus!, the user can actually get their job done unlike option 2 which is the usual naive approach to trying to prevent the user from hurting themselves.&lt;/p&gt;  &lt;p&gt;A related acronym to the PoLS is &lt;a href="http://en.wikipedia.org/wiki/DWIM"&gt;Do What I Mean&lt;/a&gt; (DWIM), which describes users’ feelings when the program they’re using does exactly what they told it to, according to its specification, but not what the user expected.&amp;#160; The best user interfaces ensure that the user is always able to find what they need where they expect it, and when they issue commands they do what the user meant for them to do.&lt;/p&gt;  &lt;p&gt;As a developer, even when you’re not working on user interfaces, remember that the Principle of Least Surprise (and DWIM) apply to every class and every method you create.&amp;#160; Expecially if you’re writing a framework or an API!&amp;#160; Try to avoid unexpected side effects in your methods, and if they must be there, ensure that the method name makes clear that they’re happening.&amp;#160; If MarkOrderAsCancelled() also deletes all of the OrderDetail records, consider renaming it to something like CancelOrderAndDeleteDetails(), for example.&amp;#160; And if a class has &lt;a href="http://stevesmithblog.com/blog/insidious-dependencies/"&gt;insidious dependencies&lt;/a&gt;, try to make this more apparent by injecting them via the constructor so users of the class are explicitly aware of them.&amp;#160; Writing software that intuitively does what’s expected, from the UI down to the individual methods, is seriously challenging but is something we as software developers should strive for every day.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/oI3KjRxWAD8" height="1" width="1"/&gt;</description></item><item><title>Silverlight Contest</title><link>http://stevesmithblog.com/blog/silverlight-contest/</link><pubDate>Wed, 08 Jul 2009 14:21:56 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/silverlight-contest/</guid><dc:creator>ssmith</dc:creator><slash:comments>1</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;&lt;a href="http://componentart.com/"&gt;ComponentArt&lt;/a&gt; recently announced their &lt;a href="http://www.componentart.com/community/competition2009/"&gt;Summer Silverlight Coding Competition&lt;/a&gt;, running June 22nd to September 22nd this summer.&amp;#160; Already there are a bunch of submissions to the contest, although there’s still lots of time left before the contest is over.&amp;#160; The winner will be determined based on the results of community voting combined with a panel of judges, so you can help decide which of these apps deserves to win the huge $10,000 prize for being the best application.&lt;/p&gt;  &lt;p&gt;Check out the list of contestants and their apps &lt;a href="http://www.componentart.com/community/competition2009/contestants.aspx"&gt;here&lt;/a&gt;.&amp;#160; Some of the applications submitted so far include collaborative whiteboarding/teaching applications, games, virtual in-browser operating systems, and online stores.&amp;#160; Find out what kinds of cool applications others are building in Silverlight and submit your own for a chance to win.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/lCxyBYhPXrA" height="1" width="1"/&gt;</description></item><item><title>Excel 2007 Named Ranges and Data Validation</title><link>http://stevesmithblog.com/blog/excel-2007-named-ranges-and-data-validation/</link><pubDate>Tue, 23 Jun 2009 19:41:00 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/excel-2007-named-ranges-and-data-validation/</guid><dc:creator>ssmith</dc:creator><slash:comments>2</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;It’s hard to find information on Excel Named Ranges for Excel 2007 using a search engine.&amp;#160; The problem isn’t that there’s no information available, but rather that most of it refers to older versions of Excel.&amp;#160; And of course, that would be fine, if Excel 2007 didn’t go and move everything around and add that darned Ribbon thing to make it impossible to find anything.&amp;#160; But I digress.&lt;/p&gt;  &lt;p&gt;Today I’m working on something in Excel and I want to be able to limit the available values the user can enter into a cell.&amp;#160; Should be pretty easy, but I’m having a hard time finding how to do it and it’s been like 5 years since I had to do this so I’m searching for help.&amp;#160; Of course, I’m probably not searching for the right terms when I say something like “limit column values excel” and get back a bunch of junk related to the maximum number of columns excel supports.&lt;/p&gt;  &lt;p&gt;Once I remembered that these things are called Named Ranges I started to make some progress.&amp;#160; What I basically wanted to do was let the user either type in or &lt;a href="http://www.ehow.com/how_2268287_dropdown-list-excel-cell.html"&gt;specify from a drop down list the values that were valid for the cell&lt;/a&gt;.&amp;#160; It turns out that this is pretty easy to do by specifying a Named Range as the source of a List in the Data Validation.&amp;#160; There are a few related tasks here, so let’s cover them one by one.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Define a Named Range&lt;/li&gt;    &lt;li&gt;Limit Valid Entries In a Cell to a List of Values&lt;/li&gt;    &lt;li&gt;Delete and Manage Named Ranges&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Defining a Named Range in Excel 2007&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is actually very easy, and allows you to later refer to the range by name rather than using its $A2:A17 nomenclature.&amp;#160; For example, let’s say that you want to limit the Company Names listed in an Excel file to a particular collection of names (e.g. your customers).&amp;#160; First, you probably want to put this list into a separate worksheet (which I’ll call &lt;em&gt;&lt;strong&gt;Lookup&lt;/strong&gt;&lt;/em&gt;) under a heading that describes the range.&amp;#160; The following diagram shows an example:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_thumb.png" width="244" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this screenshot, I’ve highlighted the Customer Names as well as the actual rows of data, but be careful not to do this when you’re defining your Named Range (go ahead, ask me how I know not to do this… or go ahead and do it and you’ll understand why the third part of this post is on deleting named ranges).&lt;/p&gt;  &lt;p&gt;So, &lt;strong&gt;highlight just the values&lt;/strong&gt; you want in your named range.&amp;#160; Then click on the white space just above the A column (where it says B2 in my screenshot above).&amp;#160; This is called the Name Box.&amp;#160; Type in the name for your range.&amp;#160; It has to be just one word, no spaces.&amp;#160; Let’s call mine CustomerNames, as shown below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_thumb_1.png" width="244" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You’ve just defined a Named Range in Excel 2007.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Limit Valid Entries In a Cell to a List of Values&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now switch to your main worksheet (using the tabs at the bottom of the Workbook) which might look like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_thumb_2.png" width="244" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Note that in this example I’ve been entering in customer names by hand, with some duplication.&amp;#160; If later on I decide to change Contoso to Contoso, Inc. and then I want to run some reports or show a pie chart displaying sales by customer, these will no longer be grouped together.&amp;#160; It’s much better to use a named range to define the list of possible values (and of course this might ultimately come from a database or web service) than to have a lot of manually entered data that could be slightly off.&lt;/p&gt;  &lt;p&gt;In Excel 2007, if you want to limit the values a particular cell can have, you should click on the cell (or range) and select the Data tab in the ribbon.&amp;#160; Then click on the Data Validation button, which will bring up the dialog shown here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_thumb_3.png" width="244" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;By default, cells can contain any value (no validation).&amp;#160; In this case, we want to change this to use a list of values, so in the Allow drop down list, choose List.&amp;#160; Then in the Source: field, put in ‘=CompanyNames’ replacing ‘CompanyNames’ with the name of your Named Range.&amp;#160; Click OK.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_10.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_thumb_4.png" width="244" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You can apply the Data Filter to the whole column – it will ignore any headers that currently don’t match (though you’ll be able to use the dropdown on these as well later should you wish to, or simply remove the validation from the header row manually afterward).&amp;#160; Now to add a new row, you can click on the dropdown arrow or start typing and get autocompletion of the data, like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_12.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_thumb_5.png" width="244" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Delete and Manage Named Ranges&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now let’s say you accidentally create a Named Range that contains more cells than you would like, or that isn’t named what you’d like.&amp;#160; You might think that you could redefine that range by highlighting a selection of cells and retyping that name into the Name Box.&amp;#160; But no, that doesn’t work.&amp;#160; Fortunately, there’s a very easy way in Excel 2007 to manage all of your Named Ranges once you know where to look for it (and no, it’s nowhere in the Data Validation section where thus far we’ve been working with Named Ranges).&amp;#160; The trick is to go to the Formula tab on the Ribbon (because frequently Named Ranges are used in Formulas, I suppose).&amp;#160; There you will find a Defined Names section which includes a Name Manager.&amp;#160; The Name Manager, as you might guess, makes it quite easy to add, edit, and delete Named Ranges from within Excel 2007.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_14.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Excel2007NamedRangesandDataValidation_E4C7/image_thumb_6.png" width="244" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Named Ranges are a handy feature in Excel.&amp;#160; Finding out how to work with them in Excel 2007 if you’re familiar with Excel 2003 or earlier can be a challenge.&amp;#160; With any luck, this post will help a few folks out or at least serve to remind me how to do this the next time I need to remember it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/pL603iYZroI" height="1" width="1"/&gt;</description></item><item><title>Silverlight 3 on XBox 360</title><link>http://stevesmithblog.com/blog/silverlight-3-on-xbox-360/</link><pubDate>Tue, 23 Jun 2009 19:18:27 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/silverlight-3-on-xbox-360/</guid><dc:creator>ssmith</dc:creator><slash:comments>5</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;&lt;a href="http://devmavens.com/ScottGuthrie"&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="image" border="0" alt="image" align="right" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/Silverlight3onXBox360_D73F/image_3.png" width="244" height="197" /&gt;&lt;/a&gt; &lt;a href="http://devmavens.com/scottguthrie"&gt;Scott Guthrie&lt;/a&gt; earlier today twittered about a sneak peek shown today of Silverlight 3 running on an XBox 360.&amp;#160; I’ve been waiting a long time for this and I really hope that the XBox platform will be able to take advantage of some of the opportunities that Silverlight has to offer.&amp;#160; I’d really like to see the XBox opened up into a more flexible app server, as well as having access to the rich variety of online games that Silverlight already offers.&amp;#160; It’s a definite win.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/JaH_Mdlxj1U" height="1" width="1"/&gt;</description></item><item><title>INVESTing in User Stories</title><link>http://stevesmithblog.com/blog/investing-in-user-stories/</link><pubDate>Mon, 22 Jun 2009 18:00:13 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/investing-in-user-stories/</guid><dc:creator>ssmith</dc:creator><slash:comments>5</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;User Stories describe features from the standpoint of the user, and should identify small units of work that can reasonably achieved within a short (1 or 2 week) iteration by a programming pair.&amp;#160; A useful acronym for remembering how to write good user stories is INVEST (more &lt;a href="http://agilesoftwaredevelopment.com/blog/vaibhav/good-user-story-invest"&gt;elsewhere&lt;/a&gt; and &lt;a href="http://www.bing.com/search?q=user+stories+invest"&gt;here&lt;/a&gt;).&amp;#160; A “good” user story is one that serves the needs of all of the stakeholders in the software development project, including the customer, the team lead (or PM), and the developer(s).&amp;#160; Ideally the story is recorded in short form on an index card (or electronic equivalent) and is a placeholder for a longer conversation that has taken place between the customer and the developer team.&amp;#160; Also ideally, it includes Acceptance Test criteria, which developers must ensure have been met before they consider the story complete.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The INVEST acronym for User Stories&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;User stories should be…&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Independent&lt;/strong&gt; – In order to be estimated and planned effectively, user stories should be independent of one another.&amp;#160; Combining or splitting stories, and also working on &lt;a href="http://stevesmithblog.com/blog/stories-too-big-ndash-vertical-slices/"&gt;vertical slices&lt;/a&gt;, are good ways to achieve this.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Negotiable&lt;/strong&gt; – The precise details of the story are open to further discussion and clarification.&amp;#160; Having too much detail in the story can limit options.&amp;#160; Developers should be encouraged to fill in necessary details with customer conversations (of course this works best with a local customer or customer proxy).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Valuable&lt;/strong&gt; – Every story needs to add business value to the customer.&amp;#160; Ideally, customers are the ones writing the user stories, to ensure they are deciding what is most valuable to work on.&amp;#160; A user story should contribute to a minimal marketable feature (MMF), either in itself or &lt;a href="http://joearnold.com/2008/03/the-minimal-marketable-feature-mmf/"&gt;in combination with several other related stories.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Estimable&lt;/strong&gt; – The story needs to be small enough and well enough understood that developers can estimate the resources required to achieve it.&amp;#160; The larger and less well-understood the story, the more difficult it will be to accurately estimate.&amp;#160; Achieving this is usually done by discussing the problem further with the customer (increase domain knowledge), performing a spike (increase technical knowledge), breaking up the story into smaller pieces (small stories are easier to estimate), or some combination of these three tactics.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Small&lt;/strong&gt; – Large stories are difficult to estimate and tend to include dependencies and hidden subtasks that can quickly scope creep them into massive &lt;em&gt;epics&lt;/em&gt;.&amp;#160; Stories should be small.&amp;#160; They should be achievable by a pair within an iteration with lots of time to spare.&amp;#160; If your iteration is one week, your maximum story size should be a few days’ work at most.&amp;#160; If it’s two weeks, you might accept a story that would take a pair a week to perform.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Testable&lt;/strong&gt; – In order for developers to know they’re done with a story, it should have a test (or tests) that prove it works.&amp;#160; This test should be written by the customer (if only in English, if not using a tool like &lt;a href="http://fit.c2.com/"&gt;Fit&lt;/a&gt;).&amp;#160; Stories should have definite criteria for success.&amp;#160; “Improve performance” or “make the UI intuitive” are impossible to nail down with numbers.&amp;#160; “Performs 20 request/sec under load with product database loaded and 100 concurrent users” is much easier to write a test for.&lt;/p&gt;  &lt;p&gt;Following the INVEST acronym should result in stories which are much easier to use in your agile estimating and planning.&amp;#160; During the iteration retrospective, pay particular attention to stories that didn’t get done during the iteration, and identify any deficiencies they have from an INVEST point of view.&amp;#160; If you’re consistently seeing the same kinds of problems with your failing stories, you’ve identified a problem with your process that you should address.&amp;#160; From a lean software development perspective, you’ll want to perform &lt;em&gt;root cause analysis&lt;/em&gt; and correct the problem, rather than working around it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/H2eKk6mYUiQ" height="1" width="1"/&gt;</description></item><item><title>Determine Whether an Assembly was compiled in Debug Mode</title><link>http://stevesmithblog.com/blog/determine-whether-an-assembly-was-compiled-in-debug-mode/</link><pubDate>Thu, 18 Jun 2009 02:48:47 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/determine-whether-an-assembly-was-compiled-in-debug-mode/</guid><dc:creator>ssmith</dc:creator><slash:comments>3</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;I’m working on a little application right now that provides some insight into the assemblies in use for a given application.&amp;#160; One of the things that I want to be able to show is whether or not each assembly was built in Debug or Release mode.&amp;#160; As you’re no doubt aware, &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx"&gt;running applications in production that were built in Debug mode can be a major performance problem&lt;/a&gt; (at a minimum – depending on what else you have turned on in Debug mode it could also be a security issue).&lt;/p&gt;  &lt;p&gt;So I did some &lt;em&gt;&lt;a href="http://bing.com/"&gt;binging&lt;/a&gt;&lt;/em&gt; (followed by &lt;a href="http://www.bing.com/search?q=binging&amp;amp;go=&amp;amp;form=QBLH"&gt;some purging&lt;/a&gt;? no, wait, that with a hard G sound) and quickly found some sample code that I was able to use in some test code to confirm that it is working.&amp;#160; Fellow MVP Bill McCarthy wrote (like, 5 years ago to the day!) about how to do this in Visual Basic.&amp;#160; Not that I have anything against VB, but my preference since VB6 has been C# (if nothing else, it makes JavaScript much easier to grok), so I had to translate the code into my native tongue, which provides me with something to share with you.&amp;#160; This is literally Bill’s code, translated by me into C#.&amp;#160; Any bugs you can probably assign to me as the translator, rather than Bill as original author.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Check If An Assembly Was Compiled In Debug Mode&lt;/strong&gt;&lt;/p&gt;  &lt;div&gt;   &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsAssemblyDebugBuild(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; filepath)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; IsAssemblyDebugBuild(Assembly.LoadFile(Path.GetFullPath(filepath)));&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsAssemblyDebugBuild(Assembly assembly)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var attribute &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; assembly.GetCustomAttributes(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        var debuggableAttribute = attribute &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; DebuggableAttribute;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(debuggableAttribute != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; debuggableAttribute.IsJITTrackingEnabled;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;(&lt;a href="http://feeds.feedburner.com/StevenSmith"&gt;subscribe&lt;/a&gt; to my blog)

  &lt;br /&gt;(&lt;a href="http://twitter.com/ardalis"&gt;follow me&lt;/a&gt; on twitter)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/qC5trKIwt5s" height="1" width="1"/&gt;</description></item><item><title>The Fibonacci Blog Post Formatter</title><link>http://stevesmithblog.com/blog/the-fibonacci-blog-post-formatter/</link><pubDate>Thu, 11 Jun 2009 19:50:00 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/the-fibonacci-blog-post-formatter/</guid><dc:creator>ssmith</dc:creator><slash:comments>2</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;&lt;a href="http://twitter.com/sadukie"&gt;Sarah&lt;/a&gt; suggested Tuesday that I write a blog PostFormatter that only changed the format of blog posts created on days that were &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;Fibonacci Sequence&lt;/a&gt; days (e.g. 1, 2, 3, 5, 8&amp;hellip;).&amp;nbsp; I&amp;rsquo;d hoped to code something like that up during my Ann Arbor talk last night but ended up not having the time, so just to show how easily this could be done, I threw something together today.&lt;/p&gt;
&lt;p&gt;First, this is for a demo application that I used in my talks this week &amp;ndash; if you want to follow along, &lt;a href="http://stevesmithblog.com/blog/asp-net-mvc-and-solid-programming-principles-june-2009/"&gt;grab the code from my last post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I already had a well-tested but not at all optimized Fib generator/tester class from some Euler problems I&amp;rsquo;d worked on as part of a coding kata, so I just reused that for the formatter.&amp;nbsp; The complete code for the new IPostFormatter implementation is shown here:&lt;/p&gt;
&lt;div&gt;
&lt;div style="border-style: none; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; FibPostFormatter : IPostFormatter&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
{&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; Post FormatPost(Post post)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        var fibChecker = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; FibonacciChecker();&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (fibChecker.IsFib(post.DatePosted.Day))&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            post.Title = &lt;span style="color: rgb(0, 96, 128);"&gt;&amp;quot;[FibDate!] &amp;quot;&lt;/span&gt; + post.Title;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        post.EncodedTitle = Utility.BuildFriendlyUrl(post.Title);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        post.Abstract = Utility.GetAbstract(post.Contents);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; post;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; FibonacciChecker&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt; fibNumbers;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; FibonacciChecker()&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            fibNumbers = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; IsFib(&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; numberToTest)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            var fibNumbers = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            fibNumbers = GenerateFibs(numberToTest);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; fibNumbers.Contains(numberToTest);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt; GenerateFibs(&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; upperBound)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            fibNumbers = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (fibNumbers.Count == 0)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                fibNumbers.Add(1);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                fibNumbers.Add(2);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; index = 2;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; term = 0;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt; (term &amp;lt;= upperBound)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                term = fibNumbers[index - 2] + fibNumbers[index - 1];&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                fibNumbers.Add(term);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                index++;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; fibNumbers;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Again, it could benefit from some optimization &amp;ndash; it was the result of a timeboxed Euler exercise and it certainly is adequate for testing of days up to and including 31.&lt;/p&gt;
&lt;p&gt;Naturally I wanted to be sure this worked, so I added the following test class:&lt;/p&gt;
&lt;div&gt;
&lt;div style="border-style: none; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; Microsoft.VisualStudio.TestTools.UnitTesting;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; SolidBlog.Controllers;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; SolidBlog.Models;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;namespace&lt;/span&gt; SolidBlog.Tests.Formatters&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
{&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    [TestClass]&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; PostFormatterTester&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;const&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; TEST_TITLE = &lt;span style="color: rgb(0, 96, 128);"&gt;&amp;quot;test title&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; FibPostFormatter _fibPostFormatter;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;const&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; EXPECTED_PREFIX = &lt;span style="color: rgb(0, 96, 128);"&gt;&amp;quot;[FibDate!] &amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        [TestInitialize]&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Setup()&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            _fibPostFormatter = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; FibPostFormatter();&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        [TestMethod]&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; FibDaysShouldBeFormattedAsFib()&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            var fibDays = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt;() {1, 2, 3, 5, 8, 13, 21};&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (var day &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; fibDays)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                Post myPost = _fibPostFormatter.FormatPost(GetTestPostForDayOfJanuary(day));&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                Assert.AreEqual(EXPECTED_PREFIX + TEST_TITLE, myPost.Title, &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                    &lt;span style="color: rgb(0, 96, 128);"&gt;&amp;quot;Didn't format title correctly for fib day &amp;quot;&lt;/span&gt; + day);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        [TestMethod]&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; NonFibDaysShouldNotBeFormattedAsFib()&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            var fibDays = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt;() { 4, 6, 7, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (var day &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; fibDays)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                Post myPost = _fibPostFormatter.FormatPost(GetTestPostForDayOfJanuary(day));&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                Assert.AreEqual(TEST_TITLE, myPost.Title, &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                    &lt;span style="color: rgb(0, 96, 128);"&gt;&amp;quot;Formatted title incorrectly for nonfib day &amp;quot;&lt;/span&gt; + day);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; Post GetTestPostForDayOfJanuary(&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; day)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            DateTime testPostDate = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; DateTime(2009, 1, day);&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            var myPost = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Post() { DatePosted = testPostDate, Title = TEST_TITLE, &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
                Abstract = &lt;span style="color: rgb(0, 96, 128);"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, Contents = &lt;span style="color: rgb(0, 96, 128);"&gt;&amp;quot;&amp;quot;&lt;/span&gt; };&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; myPost;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
        }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&amp;nbsp;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Both tests pass.&amp;nbsp; Finally, to wire this up in my blog application, I simply need to turn on the IoC stuff in global.asax (uncomment line 35) and be sure to use the new Create() action of my PostController (line 175 in PostController needs renamed to Create and the other Create() renamed to something else).&amp;nbsp; Finally, change the IPostFormatter line in ConfigureIoC() in global.asax (line 51/52) to the following:&lt;/p&gt;
&lt;div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; line-height: 12pt; background-color: rgb(244, 244, 244); width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; cursor: text;"&gt;
&lt;div style="border-style: none; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
StructureMapConfiguration.BuildInstancesOf&amp;lt;IPostFormatter&amp;gt;().TheDefaultIsConcreteType&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"&gt;
    &amp;lt;FibPostFormatter&amp;gt;();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With that you can run the app and if you happen to create a new post on one of the Fib sequence days of the month, you&amp;rsquo;ll see that it makes a note of this by prefixing the title with &amp;ldquo;[FibDate!] &amp;ldquo;.&lt;/p&gt;
&lt;p&gt;Note that to achieve this (assuming that the application we were changing already was using IoC and the refactored version of Create()) we didn&amp;rsquo;t have to change any existing code (well, ok, one line of IoC bootstrapping code).&amp;nbsp; That&amp;rsquo;s the &lt;a href="http://en.wikipedia.org/wiki/Open/closed_principle"&gt;Open/Closed Principle&lt;/a&gt;.&amp;nbsp; Adding additional features or changing the system&amp;rsquo;s behavior should not require that you change existing code, but rather that you encapsulate new behavior into new classes that can be swapped out via the interfaces used to refer to them.&lt;/p&gt;
&lt;p&gt;a2chrisn4u&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/A7EZpx0DUtY" height="1" width="1"/&gt;</description></item><item><title>ASP.NET MVC and SOLID Programming Principles June 2009</title><link>http://stevesmithblog.com/blog/asp-net-mvc-and-solid-programming-principles-june-2009/</link><pubDate>Thu, 11 Jun 2009 18:15:09 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/asp-net-mvc-and-solid-programming-principles-june-2009/</guid><dc:creator>ssmith</dc:creator><slash:comments>7</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;This week &lt;a href="http://stevesmithblog.com/blog/speaking-in-cleveland-and-ann-arbor-this-week/"&gt;I presented “Introducing ASP.NET MVC and SOLID Programming Principles” (aka SOLIDify Your ASP.NET MVC) to the Cleveland .NET SIG and the Ann Arbor .NET Developers group&lt;/a&gt;.&amp;#160; Thanks to everyone who came, it was standing room only at the Microsoft office in Cleveland and a great turnout at the SRT Solutions office in Ann Arbor, too.&amp;#160; I thought the presentation went well and had some good discussion in both locations and I enjoyed getting to see a lot of folks I know in the area whom I hadn’t seen in a while.&amp;#160; And the projector didn’t turn off every 5 minutes like &lt;a href="http://aspadvice.com/blogs/ssmith/archive/2007/11/02/Speaking-in-Ann-Arbor-November-14th.aspx"&gt;the last time I spoke in Ann Arbor&lt;/a&gt; (always bonus).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ssmith-presentations.s3.amazonaws.com/ssmith_SOLIDifyASPNETMVC_June2009.zip"&gt;ASP.NET MVC and SOLID Programming Principles Slides and Demos&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The only difference between the two talks is that for Ann Arbor I put together a 2-slide example showing how one’s solution would be organized in order to not have all projects ultimately referencing the Data Access Layer (DAL).&amp;#160; I mentioned this concept Tuesday in Cleveland but didn’t have a visual to go with it, so I threw something together for Wednesday (and eventually it will make its way into the actual presentation).&amp;#160; In fact, here are those two slides for reference:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/ASP.NETMVCandSOLIDProgrammingPrinciplesJ_C869/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/ASP.NETMVCandSOLIDProgrammingPrinciplesJ_C869/image_thumb.png" width="244" height="154" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/ASP.NETMVCandSOLIDProgrammingPrinciplesJ_C869/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/ASP.NETMVCandSOLIDProgrammingPrinciplesJ_C869/image_thumb_1.png" width="244" height="154" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;If you follow ISP and try to keep your interfaces with their consumers (typically in your business/domain model/core project) then your data access project needs to reference this project in order to implement these interfaces.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/fU7X6c1kUJw" height="1" width="1"/&gt;</description></item><item><title>Binding in ASP.NET MVC</title><link>http://stevesmithblog.com/blog/binding-in-asp-net-mvc/</link><pubDate>Wed, 10 Jun 2009 15:30:22 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/binding-in-asp-net-mvc/</guid><dc:creator>ssmith</dc:creator><slash:comments>13</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;div style="float: right"&gt;&lt;a title="Question! by -bast-, on Flickr" href="http://www.flickr.com/photos/-bast-/349497988/"&gt;&lt;img alt="Question!" src="http://farm1.static.flickr.com/158/349497988_fb751a5e3a.jpg" width="150" height="100" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;At my ASP.NET MVC + SOLID Principles talk in Cleveland last night, I had a couple of questions about binding in ASP.NET MVC.&amp;#160; For instance:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Can you still do something like &amp;lt;%= Bind(“Foo”) %&amp;gt; in your form? &lt;/li&gt;    &lt;li&gt;How does the controller that receives a POST get back the Model that was used in the form that was posted?&amp;#160; &lt;/li&gt;    &lt;li&gt;Does it have to be serializable? &lt;/li&gt;    &lt;li&gt;What if I need to bind custom types to my Model class? &lt;/li&gt;    &lt;li&gt;Doesn’t having the Model referenced in the View eliminate the need for the Controller? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I answered these last night but I thought they were common enough as a theme that they deserved their own answers here as well.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Does ASP.NET MVC Support Two Way Binding via the Bind() Syntax?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;No, not directly.&amp;#160; Rather, you can use HTML Helpers to create your UI (if you like – you can also just hand code the HTML if that’s your preference – ASP.NET MVC is all about you being in control), and then use either the built-in or a custom ModelBinder to convert the POSTed data into your class/Model.&amp;#160; More on ModelBinders below.&amp;#160; The HTML helper syntax might look like this:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div&gt;   &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;lt;%= Html.TextBox(&lt;span style="color: #006080"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;, Model.Title) %&amp;gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If you don’t like the “magic string” used in this, you might look at &lt;a href="http://www.lostechies.com/blogs/hex/archive/2009/06/09/opinionated-input-builders-for-asp-net-mvc-using-partials-part-i.aspx"&gt;Eric Hexter’s Input Builders project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does the controller that handles the POST get back the Model?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In my example last night, I had some code that looked like this (except it used a blog not a customer):&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[AcceptVerbs(HttpVerbs.Post)]&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult Create(Customer customer)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;   &lt;span style="color: #008000"&gt;// work with Customer here&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div&gt;This kind of looks like it’s using Magic, because nowhere am I having to deal with Request.Form[“CustomerName”] or CustomerTextBox.CustomerName as I would typically need to do.&amp;#160; It raises the question for some as to whether there is some kind of passing around of the serialized model (Customer) between the client and the server.&amp;#160; In fact this is not the case.&amp;#160; All that is happening here is standard HTTP, doing a POST, with the fields that were specified in the &amp;lt;form&amp;gt; on the client.&amp;#160; If our form had an &amp;lt;intput type=”text” name=”CustomerName” /&amp;gt; then the POST would include the CustomerName field and whatever value was stored in the TextBox.&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;The “magic” takes place in the form of a ModelBinder.&amp;#160; ModelBinders are responsible for the fairly common task of converting between a collection of Form values and a strongly typed Model class that should be created from these values.&amp;#160; First, let’s look at the equivalent code that doesn’t use a ModelBinder.&amp;#160; If I wanted to create my customer object more explicitly in the controller, I could do it like this:&lt;/div&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[AcceptVerbs(HttpVerbs.Post)]&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult Create(FormCollection formValues)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  var customer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  customer.FirstName = Request.Form[&lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;];&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  customer.LastName = Request.Form[&lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;];&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This gets old fast.&amp;#160; A better method that is one step closer to the ModelBinder approach would be:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[AcceptVerbs(HttpVerbs.Post)]&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult Create(FormCollection formValues)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  var customer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  UpdateModel(customer);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This helper method automatically updates the properties of the object we pass into it with the values from incoming form parameters (using reflection to match up the property names with the form names).&amp;#160; If we want to avoid dealing directly with the FormCollection in our controller, we can simply use the original signature I showed above, and have the controller take in as its parameter the model object (Customer in this case) that we want to have populated from the form.&lt;/p&gt;

&lt;p&gt;If there are problems with the population of the model object, the &lt;strong&gt;ModelState.IsValid&lt;/strong&gt; property will be false, and the ModelState will include details about the rule violations (such as a type mismatch).&amp;#160; You can find more detail on this &lt;a href="http://nerddinnerbook.s3.amazonaws.com/Part5.htm"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the Model used for a controller that handles a POST need to be serializable?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, it simply needs to have properties that can be mapped to the fields coming in from the POST.&amp;#160; The class itself is never serialized or deserialized or sent over the wire.&amp;#160; It’s simply mapped from the POSTed fields by a ModelBinder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I need to bind custom types to my Model class?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this case, you’ll want to write your own ModelBinder and register it so that ASP.NET MVC knows to use it when faced with a given type in your application.&amp;#160; Writing a ModelBinder simply requires that you inherit from &lt;strong&gt;DefaultModelBinder&lt;/strong&gt; and override the ConvertType() method.&amp;#160; In order to register your type with its custom ModelBinder, you would do this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;// In Global.asax Application Start or an HttpModule&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;ModelBinders.Binders.Add(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Customer), &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerBinder());&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here is a &lt;a href="http://www.singingeels.com/Articles/Model_Binders_in_ASPNET_MVC.aspx"&gt;good example of writing a custom ModelBinder class&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doesn’t having the Model referenced in the View eliminate the need for the Controller?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In response to seeing code in the View like this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;lt;%= ViewData.Model.FirstName %&amp;gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Someone asked if this was stepping on the responsibilities of the Controller, since the View was talking directly to the Model.&amp;#160; Here there can be differing opinions.&amp;#160; It’s not strictly required that you pass your Model classes to the View.&amp;#160; You can simply pass in collections of strings via ViewData.&amp;#160; Another common approach is to use a &lt;strong&gt;DTO&lt;/strong&gt; (Data Transfer Object) or &lt;strong&gt;ViewModel&lt;/strong&gt; (the “VM” in the MVVM palindrome pattern) which typically is a subset of one or more Model classes in your application that contains only the information necessary for a given View.&amp;#160; It’s also not uncommon to pass your Model into the View.&amp;#160; It’s a matter of preference and there are pros and cons to these approaches.&lt;/p&gt;

&lt;p&gt;What is not recommended is for your Model (the Customer in my example here, which has a FirstName property) to be persistence aware and to magically go and fetch itself from the database when it is referenced by the View.&amp;#160; The above code should only work if the Controller has explicitly passed in the Model to the View, using code like this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; View(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; id)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  Customer customer = customerRepository.GetCustomer(id);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View(customer);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div&gt;It is still the responsibility of the Controller to pass in whatever data the view needs.&amp;#160; The view should not have this responsibility.&amp;#160; Nor should the model know how to persist itself.&amp;#160; This &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;separation of concerns&lt;/a&gt; ensures loose coupling, testability, and a more flexible design.&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;An example of using a ViewModel/DTO would be something like this:&lt;/div&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CustomerSummaryViewModel&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; FirstName { get; set; }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; LastName { get; set; }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DateTime DateOfLastPurchase { get; set; }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  publi DateTiem AmountOfLastPurchase { get; set; }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;...&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Summary(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; id)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  Customer customer = customerRepository.GetCustomer(id);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  Order order = orderRepository.List(id).Take(1); &lt;span style="color: #008000"&gt;// gets most recent order&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  var summary = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerSummaryViewModel() {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    FirstName = customer.FirstName,&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    LastName = customer.LastName,&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    DateOfLastPurchase = order.DatePurchased,&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    AmountOfLastPurchase = order.Amount };&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View(summary);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;
Using this approach, the View will have access only to the exact pieces of data that it requires, and no more.&amp;#160; If you want to ensure that the View never calls methods on your Model objects or you want to verify with tests that your View is receiving exactly the data that it needs, then using this ViewModel/DTO approach can be valuable.&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/6iNcsXzoSvE" height="1" width="1"/&gt;</description></item><item><title>DRY - Don’t Repeat Yourself - Motivator</title><link>http://stevesmithblog.com/blog/dry-don-rsquo-t-repeat-yourself-motivator/</link><pubDate>Mon, 08 Jun 2009 17:16:00 GMT</pubDate><guid isPermaLink="true">http://stevesmithblog.com/blog/dry-don-rsquo-t-repeat-yourself-motivator/</guid><dc:creator>ssmith</dc:creator><slash:comments>4</slash:comments><category domain="http://stevesmithblog.com/blog/">Blog</category><description>&lt;p&gt;I’ve been meaning to create a DRY (Don’t Repeat Yourself) motivational poster for a while now, ever since seeing &lt;a href="http://www.lostechies.com/blogs/derickbailey/archive/2009/02/11/solid-development-principles-in-motivational-pictures.aspx"&gt;Derick Bailey’s SOLID posters&lt;/a&gt;.&amp;#160; To me, DRY is at the heart of many software patterns and principles, and sums up much better the similar Once and Only Once principle (which, to me, violates DRY right in its own name).&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Duplication is waste.&lt;/strong&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Repetition in process calls for automation; repetition in logic calls for abstraction.&lt;/strong&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;Refactor to remove wasteful repetition as often as you possibly can, and watch your software design improve.&amp;#160; Post this on the wall in your team room (along with others) to keep this principle in mind as you’re writing code.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/DRYDontRepeatYourselfMotivator_BA85/dontrepeatyourself_motivator_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="dontrepeatyourself_motivator" border="0" alt="dontrepeatyourself_motivator" src="http://stevesmithblog.com/files/media/image/WindowsLiveWriter/DRYDontRepeatYourselfMotivator_BA85/dontrepeatyourself_motivator_thumb.jpg" width="244" height="196" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Create similar motivational posters using &lt;a href="http://bighugelabs.com/flickr/motivator.php"&gt;Motivator&lt;/a&gt;.&lt;/p&gt;  &lt;h5&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h5&gt;  &lt;h5&gt;&lt;strong&gt;Creative Commons License&lt;/strong&gt;&lt;/h5&gt;  &lt;p&gt;Since I bugged Derick about having a license on his images, it’s only fair that I include one here as well.&amp;#160; It’s simply a &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/us/"&gt;Creative Commons license&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://creativecommons.org/licenses/by-sa/3.0/us/"&gt;&lt;img alt="Creative Commons License" src="http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/StevenSmith/~4/d8K1V0rUPmE" height="1" width="1"/&gt;</description></item></channel></rss>
