<?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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Jimmy Bogard</title><link>http://www.lostechies.com/blogs/jimmy_bogard/default.aspx</link><description>Professional driver on closed road.  Do not attempt.</description><language>en</language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/GrabBagOfT" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>How not to do Dependency Injection, in NerdDinner</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/2BwwdFMz5n8/how-not-to-do-dependency-injection-in-nerddinner.aspx</link><category>Refactoring</category><category>ASP.NET MVC</category><category>StructureMap</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Fri, 03 Jul 2009 09:19:29 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22612</guid><description>&lt;p&gt;Checking out the &lt;a href="http://nerddinner.codeplex.com/"&gt;NerdDinner&lt;/a&gt; code the other day, I found a common Dependency Injection anti-pattern.&amp;#160; One of the core concepts of DI is that components are not responsible for locating their own dependencies.&amp;#160; The code went part of the way to full-on DI, but not quite far enough.&amp;#160; Here’s the offending code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SearchController &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Controller &lt;/span&gt;{

&lt;span style="color:#2b91af;"&gt;IDinnerRepository &lt;/span&gt;dinnerRepository;

&lt;span style="color:green;"&gt;//
// Dependency Injection enabled constructors

&lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;SearchController()
    : &lt;span style="color:blue;"&gt;this&lt;/span&gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DinnerRepository&lt;/span&gt;()) {
}

&lt;span style="color:blue;"&gt;public &lt;/span&gt;SearchController(&lt;span style="color:#2b91af;"&gt;IDinnerRepository &lt;/span&gt;repository) {
    dinnerRepository = repository;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The second constructor is correct – the SearchController’s dependencies are passed in through the constructor.&amp;#160; This is because the IDinnerRepository is a required, or primal dependency.&amp;#160; SearchController depends on IDinnerRepository to function properly, and won’t work without it.&amp;#160; But on the first constructor, we violate DI by having the SearchController create a concrete DinnerRepository!&amp;#160; We’re now back to concrete, opaque dependencies.&amp;#160; We have a small benefit of easier testability, but we still force our controller to locate its own dependencies.&lt;/p&gt;

&lt;p&gt;So why is this a Bad Thing?&lt;/p&gt;

&lt;p&gt;For one, it’s confusing to have two constructors.&amp;#160; Why go through all the trouble of creating the IDinnerRepository interface if I’m just going to depend directly on an implementer?&amp;#160; Now what if DinnerRepository now needs some dependency?&amp;#160; What if it now needs some ILogger, security or policy dependency?&amp;#160; Do I now need to go fix all of my calls to “new”?&lt;/p&gt;

&lt;p&gt;And that’s the whole point of Dependency Injection, and the Dependency Inversion Principle.&amp;#160; I only know about my first level dependencies, and abstractions on top of that.&amp;#160; If we check out DinnerRepository, we see another issue:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DinnerRepository &lt;/span&gt;: NerdDinner.Models.&lt;span style="color:#2b91af;"&gt;IDinnerRepository &lt;/span&gt;{

    &lt;span style="color:#2b91af;"&gt;NerdDinnerDataContext &lt;/span&gt;db = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NerdDinnerDataContext&lt;/span&gt;();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;A private, opaque dependency to NerdDinnerDataContext.&amp;#160; If we wanted to make that opaque dependency explicit, we’d have to fix our SearchController (and all the other controllers as well).&amp;#160; It’s these kinds of ripple effects that prevent refactoring and improvement.&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Fixing it&lt;/h3&gt;

&lt;p&gt;But we can fix this, quite easily.&amp;#160; From &lt;a href="http://www.codeplex.com/MVCContrib"&gt;MvcContrib&lt;/a&gt;, we can grab any one of the ControllerFactory implementations for the IoC container of our choice.&amp;#160; For me, that’s &lt;a href="http://structuremap.sourceforge.net/Default.htm"&gt;StructureMap&lt;/a&gt;.&amp;#160; First, we’ll need to configure StructureMap to wire up all of our dependencies.&amp;#160; The preferred way to do so is to create a Registry:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NerdDinnerRegistry &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Registry
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;NerdDinnerRegistry()
    {
        Scan(scanner =&amp;gt;
        {
            scanner.TheCallingAssembly();
            scanner.WithDefaultConventions();
        });

        ForRequestedType&amp;lt;&lt;span style="color:#2b91af;"&gt;NerdDinnerDataContext&lt;/span&gt;&amp;gt;()
            .CacheBy(&lt;span style="color:#2b91af;"&gt;InstanceScope&lt;/span&gt;.HttpContext)
            .TheDefault.Is.ConstructedBy(() =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NerdDinnerDataContext&lt;/span&gt;());
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In the first part, we just tell StructureMap to scan the calling assembly with default conventions.&amp;#160; This will wire up IDinnerRepository to DinnerRepository.&amp;#160; Probably 99% of our dependencies will be taken care of in that one call.&amp;#160; Next, we need to wire up the NerdDinnerDataContext (for reasons we’ll see soon).&amp;#160; Since that class has multiple constructors, StructureMap likes to use the greediest dependency, with the most arguments.&amp;#160; I don’t want that, so I override it to use the no-arg constructor.&amp;#160; Finally, I cache it by HttpContext, though I could probably go Singleton if it’s expensive to instantiate.&lt;/p&gt;

&lt;p&gt;Next, I need a wrapper class to initialize StructureMap:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IoCContainer
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static void &lt;/span&gt;Configure()
    {
        &lt;span style="color:#2b91af;"&gt;ObjectFactory&lt;/span&gt;.Initialize(init =&amp;gt;
        {
            init.AddRegistry&amp;lt;&lt;span style="color:#2b91af;"&gt;NerdDinnerRegistry&lt;/span&gt;&amp;gt;();
        });
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Initialize only needs to get called once per AppDomain, and all I need to do is add the NerdDinnerRegistry I created earlier.&amp;#160; I &lt;em&gt;could&lt;/em&gt; wire up everything here, but again, the preferred configuration method is through registries.&amp;#160; The next piece is to wire up ASP.NET MVC to both call our configuration method and use the StructureMapControllerFactory:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;void &lt;/span&gt;Application_Start()
{
    RegisterRoutes(&lt;span style="color:#2b91af;"&gt;RouteTable&lt;/span&gt;.Routes);

    &lt;span style="color:#2b91af;"&gt;IoCContainer&lt;/span&gt;.Configure();
    &lt;span style="color:#2b91af;"&gt;ControllerBuilder&lt;/span&gt;.Current.SetControllerFactory(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;StructureMapControllerFactory&lt;/span&gt;());

    &lt;span style="color:#2b91af;"&gt;ViewEngines&lt;/span&gt;.Engines.Clear();
    &lt;span style="color:#2b91af;"&gt;ViewEngines&lt;/span&gt;.Engines.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MobileCapableWebFormViewEngine&lt;/span&gt;());
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I put all this in with the other MVC configuration in the Global.asax Application_Start method.&amp;#160; One final piece is to remove the extra constructors on our controller:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DinnersController &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Controller &lt;/span&gt;{

    &lt;span style="color:#2b91af;"&gt;IDinnerRepository &lt;/span&gt;dinnerRepository;

    &lt;span style="color:green;"&gt;//
    // Dependency Injection enabled constructors

    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;DinnersController(&lt;span style="color:#2b91af;"&gt;IDinnerRepository &lt;/span&gt;repository) {
        dinnerRepository = repository;
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And make our DinnerRepository expose its dependencies explicitly:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DinnerRepository &lt;/span&gt;: NerdDinner.Models.&lt;span style="color:#2b91af;"&gt;IDinnerRepository &lt;/span&gt;{
    
    &lt;span style="color:blue;"&gt;private readonly &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NerdDinnerDataContext &lt;/span&gt;db;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DinnerRepository(&lt;span style="color:#2b91af;"&gt;NerdDinnerDataContext &lt;/span&gt;db)
    {
        &lt;span style="color:blue;"&gt;this&lt;/span&gt;.db = db;
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Note that there are no no-arg constructors to be found!&amp;#160; When StructureMap creates a DinnersController, it will look to resolve the IDinnerRepository dependency.&amp;#160; That’s a DinnerRepository, which in turn needs the NerdDinnerDataContext.&amp;#160; But that’s all hidden from us, we never need to wire up an entire graph, as we would if we stuck to the “new” operator.&amp;#160; Just to make sure everything works, I can navigate to view upcoming dinners:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_411EA2FB.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://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_thumb_5F00_34149D1D.png" width="644" height="437" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h3&gt;Wrapping it up&lt;/h3&gt;

&lt;p&gt;In the original NerdDinner code, dependency inversion was only partially implemented as the original controllers still contained a constructor that called a constructor of a concrete class.&amp;#160; To fix this, we added StructureMap to the mix, configuring ASP.NET MVC to use StructureMap to create controllers instead of the default controller factory.&amp;#160; Finally, we pushed the dependency inversion principle all the way down to our repository, removing the opaque dependencies where we found them.&amp;#160; When we finished, all of our classes exposed their dependencies explicitly through their constructor.&amp;#160; No one class knew more than one level of depth, and our controllers now properly depended exclusively on the IDinnerRepository abstraction.&lt;/p&gt;

&lt;p&gt;In the future, we can add things like logging, policies and the like to custom IDinnerRepository implementations, without needing to change any of our controllers.&amp;#160; Once we introduce inversion of control to our application, we open a lot of doors for functionality and simplicity, but only going halfway won’t give us the full benefit.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22612" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=2BwwdFMz5n8:WumYr2j9BYI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=2BwwdFMz5n8:WumYr2j9BYI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=2BwwdFMz5n8:WumYr2j9BYI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=2BwwdFMz5n8:WumYr2j9BYI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=2BwwdFMz5n8:WumYr2j9BYI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/2BwwdFMz5n8" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">21</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22612</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/07/03/how-not-to-do-dependency-injection-in-nerddinner.aspx</feedburner:origLink></item><item><title>Congrats to the Los Techies MVPs!</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/y8UtGr1BzMI/congrats-to-the-los-techies-mvps.aspx</link><category>Misc</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Wed, 01 Jul 2009 18:03:38 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22574</guid><description>&lt;p&gt;This morning, I and fellow Los Techies alumni Eric Hexter and Chris Patterson learned that we are MVPs!&amp;#160; Well, technically I learned last night through an IM of a re-tweet of my MVP lead, but hey, close enough, right?&amp;#160; I know it’s cheesy, but I think these awards are a testament to the great community Los Techies has built over the years, so for me, this is really an award for Los Techies.&amp;#160; The roundup includes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Jimmy Bogard, MVP ASP.NET&lt;/li&gt;    &lt;li&gt;Eric Hexter, MVP ASP.NET&lt;/li&gt;    &lt;li&gt;Chris Patterson, MVP C#&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Personally, I’ve viewed my community involvement as simply a desire to share my journey with others, and in turn learn where others have been and are going.&amp;#160; My favorite experiences thus far have been the open space conferences, book clubs, dojos and code camps, as it gives me a great chance to meet and talk with a lot of smart people.&amp;#160; Thanks again everyone!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22574" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=y8UtGr1BzMI:Y9ldva2pZcQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=y8UtGr1BzMI:Y9ldva2pZcQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=y8UtGr1BzMI:Y9ldva2pZcQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=y8UtGr1BzMI:Y9ldva2pZcQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=y8UtGr1BzMI:Y9ldva2pZcQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/y8UtGr1BzMI" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22574</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/07/01/congrats-to-the-los-techies-mvps.aspx</feedburner:origLink></item><item><title>How we do MVC – View models</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/_fYk6Mp_QV0/how-we-do-mvc-view-models.aspx</link><category>ASP.NET MVC</category><category>AutoMapper</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Mon, 29 Jun 2009 20:06:36 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22505</guid><description>&lt;p&gt;A while back, I went over a few of the patterns and opinions we’ve gravitated towards on our current large-ish ASP.NET MVC project, or, &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/04/24/how-we-do-mvc.aspx"&gt;how we do MVC&lt;/a&gt;.&amp;#160; Many of these opinions were forged the hard way, by doing the wrong thing many times until we found the “right” opinion.&amp;#160; Of course, many of these opinions are only really valid in the constraints of our project.&amp;#160; While the domain of this project isn’t important, here are some key aspects to consider:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;AJAX is used very, very sparingly.&amp;#160; Section 508 compliance is required&lt;/li&gt;    &lt;li&gt;XHTML compliance is also required&lt;/li&gt;    &lt;li&gt;XHTML DTD validation is also required&lt;/li&gt;    &lt;li&gt;All (well, 99%) operations revolve a single uber-entity.&amp;#160; Think customer relationship management, where everything you do deals with exactly one customer&lt;/li&gt;    &lt;li&gt;Snippets of information repeated across many screens&lt;/li&gt;    &lt;li&gt;Screens are either edit, or view, but never both.&amp;#160; (99% never)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Given these constraints, these opinions may or may not apply to the project you work on.&amp;#160; Again, patterns are all about tradeoffs, benefits and liabilities.&amp;#160; But, opinionated software is like building a bullet train.&amp;#160; It goes extremely fast, but only in the direction you build it.&lt;/p&gt;  &lt;p&gt;That said, I’m going to go over some of the main aspects of our MVC usage in a series of posts – starting with ViewModels.&lt;/p&gt;  &lt;h3&gt;ViewModel design&lt;/h3&gt;  &lt;p&gt;For our application, the ViewModel is a central aspect of our MVC architecture.&amp;#160; One of the first dilemmas facing MVC developers is to decide what the “M” in MVC means in ASP.NET MVC.&amp;#160; In Rails, this is fairly clear, the M is ActiveRecord (by default).&amp;#160; But in ASP.NET MVC, the “M” is silent!&amp;#160; Its out-of-the-box architecture offers no guidelines nor advice on what the M should be.&amp;#160; Should it be an entity?&amp;#160; Data access object?&amp;#160; DTO?&amp;#160; Something else?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Sidenote – the term DTO is far overused.&amp;#160; DTO is a &lt;a href="http://martinfowler.com/eaaCatalog/dataTransferObject.html"&gt;Data Transfer Object&lt;/a&gt;.&amp;#160; The pattern describes the usage, not the shape of a type.&amp;#160; Just because an object is all properties and no methods does NOT mean it’s a DTO.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;For us, the ViewModel is inextricably linked to Views, which leads us to our first rule:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Rule #1 – All Views are strongly-typed&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I think I’ve gone over this one enough, as I really can’t stand magic strings and loose contracts.&amp;#160; A dictionary as ViewModel is a very loose contract between the Controller and View.&amp;#160; While on rare occasions we still need to pass information in the dictionary part, we’ve limited this to supporting information to help render some of the lower-level pieces of the View, and are used for some “plumbing” pieces, these pieces do not show up in our Controller action nor are they visible when you design the view.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Rule #2 – For each ViewModel type, there is defined exactly one strongly typed View&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We’ll get into how we do this soon, but this rule has a lot of implications:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ViewModel types are distinct from our Domain Model types&lt;/li&gt;    &lt;li&gt;The choice of what View to show can be decided strictly on the shape of your ViewModel&lt;/li&gt;    &lt;li&gt;Re-used pieces in a View (through Partials) can be decided through re-using ViewModel types&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_05CE4D53.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="153" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_thumb_5F00_6C664A18.png" width="425" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;On the first point, we never pass an Domain Model entity straight into the view.&amp;#160; Most of the time, we only show a slice of information from a single entity.&amp;#160; And many other times, the same snippet is shown in many places.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Rule #3 – The View dictates the design of the ViewModel.&amp;#160; Only what is required to render a View is passed in with the ViewModel.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If a Customer object has fifty properties, but one component only shows their name, then we create a custom ViewModel type with &lt;em&gt;only those two properties&lt;/em&gt;.&amp;#160; Because we only have one ViewModel type per View, we shape our ViewModel around only what is displayed (or used) in that View.&amp;#160; Why is this a Good Thing?&lt;/p&gt;  &lt;p&gt;For one, just having a ViewModel points us to the right View.&amp;#160; We need any other information other than your ViewModel type to pick the correct View.&amp;#160; This also means we no longer need to concern ourselves with locating views by some arbitrary name, as the ViewModel &lt;em&gt;is&lt;/em&gt; the View.&amp;#160; Things like RenderPartial, which I have to select a name, become rather pointless at that point.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Rule #4 – The ViewModel contains only data and behavior related to the View&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;For the most part, our ViewModel contains only data.&amp;#160; Most, if not all aggregations/calculations or shaping is done through our Domain Model.&amp;#160; But occasionally, we have View-specific behavior or information, and that rightly belongs on our ViewModel.&lt;/p&gt;  &lt;p&gt;We’ve looked at how we design our ViewModel and what it looks like, but how does it get there?&amp;#160; If we create all these distinct ViewModel types separate from our Domain Model, didn’t we just create a bunch of work for ourselves?&amp;#160; We thought so too, which is why we developed &lt;a href="http://automapper.codeplex.com/"&gt;AutoMapper&lt;/a&gt; on this project.&lt;/p&gt;  &lt;h3&gt;Building the ViewModel&lt;/h3&gt;  &lt;p&gt;When we introduced AutoMapper into our MVC pipeline, we had a real problem.&amp;#160; Do Controllers need to do the mapping between Domain Model and ViewModel in each action method?&amp;#160; That becomes rather annoying for unit testing, as the mapping operation could warp things to a state that it becomes difficult to pull things back out.&amp;#160; For example, or EditModels (ViewModels for forms) are very string-y, where DateTimes, Ints, Decimals etc are represented as strings.&amp;#160; This comes from us using Castle Validators (future post, I promise) for validation.&amp;#160; &lt;/p&gt;  &lt;p&gt;So more moving parts, a dependency across &lt;em&gt;all&lt;/em&gt; controllers?&amp;#160; No, mapping in our Controller action just won’t do.&amp;#160; Instead, we’ll use an Action Filter to do the work for us:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_2510F426.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="209" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_thumb_5F00_1D1951C4.png" width="744" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;A request comes in, handled by an Action.&amp;#160; The Action does its thing, ultimately deciding how to respond to the request.&amp;#160; In many cases, this means rendering a view (ViewResult).&amp;#160; From there, our Action Filter comes into play.&amp;#160; On our Action method, we decorate it with an AutoMap attribute to configure the source/destination type pair to be mapped:&lt;/p&gt;  &lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;AutoMap&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Product&lt;/span&gt;), &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ShowProduct&lt;/span&gt;))]
&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ActionResult &lt;/span&gt;Details(&lt;span style="color:blue;"&gt;int &lt;/span&gt;id)
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;product = _productRepository.GetById(id);

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;View(product);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Very trivial, yes, but here we see that we still use the strongly-typed version of the View method, so that means that our model on the Action side, which I call the Presentation Model (feel free to pick a better name), is the strongly-typed ViewModel &lt;em&gt;for the moment&lt;/em&gt;.&amp;#160; The Presentation Model, which the Action creates, can be an entity, an aggregate root, or some other &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/02/04/ddd-aggregate-component-pattern-in-action.aspx"&gt;custom aggregate component&lt;/a&gt; that we build up.&lt;/p&gt;

&lt;p&gt;From there, we decorated our action with a filter that specified we need to map from Product to ShowProduct.&amp;#160; Why do we have to specify the source type?&amp;#160; Well, many ORMs, including NHibernate, rely on proxy types for things like lazy loading.&amp;#160; Instead of relying on the runtime type, we’ll explicitly specify our source type directly.&amp;#160; This also helps us later in testing, as we can whip through all of our controller actions using reflection, and test to make sure the source/destination type specified is actually configured.&lt;/p&gt;

&lt;p&gt;The filter attribute is very simple:&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;AttributeUsage&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;AttributeTargets&lt;/span&gt;.Method, AllowMultiple = &lt;span style="color:blue;"&gt;false&lt;/span&gt;)]
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AutoMapAttribute &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;ActionFilterAttribute
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private readonly &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;_sourceType;
    &lt;span style="color:blue;"&gt;private readonly &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;_destType;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;AutoMapAttribute(&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;sourceType, &lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;destType)
    {
        _sourceType = sourceType;
        _destType = destType;
    }

    &lt;span style="color:blue;"&gt;public override void &lt;/span&gt;OnActionExecuted(&lt;span style="color:#2b91af;"&gt;ActionExecutedContext &lt;/span&gt;filterContext)
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;filter = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AutoMapFilter&lt;/span&gt;(SourceType, DestType);

        filter.OnActionExecuted(filterContext);
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;SourceType
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;_sourceType; }
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;DestType
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;_destType; }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;We simply capture the types and delegate to the real action filter for the work.&amp;#160; This is again because I believe in separating metadata in attributes from the behavior they perform.&amp;#160; Attributes just don’t work well for behavior.&amp;#160; Instead, I’ll create a separate action filter:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AutoMapFilter &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;BaseActionFilter
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private readonly &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;_sourceType;
    &lt;span style="color:blue;"&gt;private readonly &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;_destType;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;AutoMapFilter(&lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;sourceType, &lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;destType)
    {
        _sourceType = sourceType;
        _destType = destType;
    }

    &lt;span style="color:blue;"&gt;public override void &lt;/span&gt;OnActionExecuted(&lt;span style="color:#2b91af;"&gt;ActionExecutedContext &lt;/span&gt;filterContext)
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;model = filterContext.Controller.ViewData.Model;

        &lt;span style="color:blue;"&gt;object &lt;/span&gt;viewModel = &lt;span style="color:#2b91af;"&gt;Mapper&lt;/span&gt;.Map(model, _sourceType, _destType);

        filterContext.Controller.ViewData.Model = viewModel;
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The BaseActionFilter is just a class that implements the various filter methods as virtual members, so I can override just the ones I need to use.&amp;#160; The AutoMapFilter pulls the original PresentationModel out of ViewData, performs the mapping operation, and puts the mapped ViewModel into the ViewData.Model property.&amp;#160; From there, the strongly-typed view for our specified ViewModel type is rendered.&lt;/p&gt;

&lt;p&gt;Because AutoMapper can flatten source types, we often find our ViewModel to simply follow a property chain for various pieces of information.&amp;#160; Again, we let our View shape that piece.&amp;#160; If we decide not to flatten, it’s usually because we’re creating a partial that re-uses a ViewModel type across other parent ViewModel types.&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Wrapping it up&lt;/h3&gt;

&lt;p&gt;Designing ViewModels is quite ambiguous with MVC, as the shipped platform doesn’t offer any guidance or opinions in that area.&amp;#160; But by forming rules around our ViewModel, we can create a path and direction for our innovation.&amp;#160; Our rules are designed to strengthen the relationship between the View and the Model, with a concept of ViewModel – a Model designed exclusively for exactly one View.&lt;/p&gt;

&lt;p&gt;In the next post, we’ll look at designing our views – for both viewing and editing data, and how we’ve crafted opinionated HTML builders to eliminate a lot of duplication and enforce standardization.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22505" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=_fYk6Mp_QV0:qM44NXGkt8o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=_fYk6Mp_QV0:qM44NXGkt8o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=_fYk6Mp_QV0:qM44NXGkt8o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=_fYk6Mp_QV0:qM44NXGkt8o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=_fYk6Mp_QV0:qM44NXGkt8o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/_fYk6Mp_QV0" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">27</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22505</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx</feedburner:origLink></item><item><title>Expressions Cheat Sheet</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/C85ybKkBOoM/expressions-cheat-sheet.aspx</link><category>C#</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Wed, 24 Jun 2009 19:36:53 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22412</guid><description>&lt;p&gt;I started getting really tired of looking up the translation between the ExpressionType and concrete Expression type (they don’t match up), so I created this cheat sheet that has each ExpressionType, derived Expression type and a simple example.&amp;#160; What’s interesting is a few are only available in VB.NET, but no one really wants non-short-circuited Or/And operators, do they?&amp;#160; You can &lt;a href="http://grabbagoftimg.s3.amazonaws.com/Expression%20Cheat%20Sheet.pdf"&gt;download the PDF version&lt;/a&gt;, or just view the big list in all its glory:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;ExpressionType&lt;/td&gt;        &lt;td&gt;Type&lt;/td&gt;        &lt;td&gt;Example&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Add&lt;/td&gt;        &lt;td&gt;BinaryExpression&lt;/td&gt;        &lt;td&gt;         &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;int &lt;/span&gt;i = 2, j = 3;
&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt; example = () =&amp;gt; i + j;&lt;/pre&gt;
        &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;AddChecked&lt;/td&gt;

      &lt;td&gt;BinaryExpression&lt;/td&gt;

      &lt;td&gt;
        &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;int &lt;/span&gt;i = &lt;span style="color:#2b91af;"&gt;Int32&lt;/span&gt;.MaxValue, j = 1;
&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt; example = () =&amp;gt; &lt;span style="color:blue;"&gt;checked&lt;/span&gt;(i + j);&lt;/pre&gt;
        &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;And&lt;/td&gt;

      &lt;td&gt;BinaryExpression&lt;/td&gt;

      &lt;td&gt;
        &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Dim &lt;/span&gt;i &lt;span style="color:blue;"&gt;As Boolean &lt;/span&gt;= &lt;span style="color:blue;"&gt;True&lt;/span&gt;, j &lt;span style="color:blue;"&gt;As Boolean &lt;/span&gt;= &lt;span style="color:blue;"&gt;False
Dim &lt;/span&gt;sample &lt;span style="color:blue;"&gt;As &lt;/span&gt;BLOCKED EXPRESSION =&amp;gt; c &lt;span style="color:blue;"&gt;is int&lt;/span&gt;;&lt;/pre&gt;
        &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;This is only for C# 3.0, the .NET 4.0 list should grow quite a bit.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22412" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=C85ybKkBOoM:ZbKopuhkxb8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=C85ybKkBOoM:ZbKopuhkxb8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=C85ybKkBOoM:ZbKopuhkxb8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=C85ybKkBOoM:ZbKopuhkxb8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=C85ybKkBOoM:ZbKopuhkxb8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/C85ybKkBOoM" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22412</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/24/expressions-cheat-sheet.aspx</feedburner:origLink></item><item><title>The Filter-ViewData anti-pattern</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/lo1E7YJQTPs/the-filter-viewdata-anti-pattern.aspx</link><category>ASP.NET MVC</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Thu, 18 Jun 2009 20:08:30 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22198</guid><description>&lt;p&gt;In just about every website you go to these days, its layout follows a very similar pattern:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_5A250E48.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="362" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_thumb_5F00_55425A8C.png" width="521" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You have some static resource logo, a large main section with information that our controller action supplies.&amp;#160; But we also have some other stuff, those green sections.&amp;#160; Things like breadcrumbs, shopping carts, login widgets, smart menus and so on.&amp;#160; It’s all still data driven, but its information has absolutely &lt;em&gt;nothing&lt;/em&gt; to do with what’s going on in my main section.&amp;#160; This is some of the first kinds of duplication we see in MVC applications – common, data-driven sections across many pages in our application.&lt;/p&gt;  &lt;p&gt;The usual way to get rid of this duplication is through ActionFilters.&amp;#160; We decorate our main section action with filters:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ProductController &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Controller
&lt;/span&gt;{
    [&lt;span style="color:#2b91af;"&gt;LoginInfo&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ActionResult &lt;/span&gt;Index()
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;products = _productRepository.FindAll();

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;View(products);
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;We don’t have that duplicated login information code in all of our controllers, and we can even go so far as to decorating our controller class or layer supertype to apply our filter to a broad set of controllers.&amp;#160; But looking at our filter, it looks like we took a step backwards:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LoginInfoAttribute &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;ActionFilterAttribute
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public override void &lt;/span&gt;OnActionExecuted(&lt;span style="color:#2b91af;"&gt;ActionExecutedContext &lt;/span&gt;filterContext)
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;currentUser = _userSession.GetCurrentUser();

        filterContext.Controller.ViewData.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;currentUser&amp;quot;&lt;/span&gt;, currentUser);
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Back again to magic strings!&amp;#160; With &lt;a href="http://www.codeplex.com/MVCContrib"&gt;MVC Contrib&lt;/a&gt;, it looks a little better as we can skip the key part, and just pass the current user object in.&amp;#160; But beyond the magic strings issue here is the problem of linking what is essentially a view concern (how I organize the different pieces of information on a given page) with my controller structure.&amp;#160; What if that widget isn’t shown on all actions for a controller?&amp;#160; What if I have four widgets, and not all are shown on every screen?&amp;#160; It begins to break down the normal, filters-on-layersupertypes-pattern.&amp;#160; I’d rather not let my view structure, with master pages and what not, influence my main-line controller design in any way.&lt;/p&gt;

&lt;p&gt;The other issue I run into is figuring out where the heck the information comes from if I’m looking at a view.&amp;#160; I see a piece being pulled out of ViewData, but not any clear indication of where that information came from:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="background:#ffee62;"&gt;&amp;lt;%&lt;/span&gt; Html.RenderPartial(&lt;span style="color:#a31515;"&gt;&amp;quot;loginView&amp;quot;&lt;/span&gt;, ViewData[&lt;span style="color:#a31515;"&gt;&amp;quot;currentUser&amp;quot;&lt;/span&gt;]); &lt;span style="background:#ffee62;"&gt;%&amp;gt;

&lt;/span&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;View Products&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Yes, we can put this in a master page.&amp;#160; But now we’ve coupled the requirements of our view structure with the structure of our controllers, not always a good thing.&amp;#160; In my (not-so) humble opinion, &lt;strong&gt;an action should be responsible for generating exactly one model&lt;/strong&gt;.&amp;#160; Things like action filters fiddling with view data are three layers of indirection to get around this rule.&amp;#160; But in the &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471#DownloadId=61773"&gt;MVC Futures&lt;/a&gt; assembly, we have a different option.&lt;/p&gt;

&lt;h3&gt;Tangential concerns with RenderAction&lt;/h3&gt;

&lt;p&gt;In our original view, if we dissected each piece, we had a main section and other, orthogonal sections.&amp;#160; The main section’s information is handled by our main action handling the request.&amp;#160; The other pieces are needed, but those concerns aren’t really related to the main section.&amp;#160; Does showing a login widget have anything to do with showing a product list?&amp;#160; No.&amp;#160; But I don’t want to couple all the different concerns in completed view with the main action.&amp;#160; Because those widgets, and where they’re located is a view concern, we can initiate the rendering of those pieces from the view using RenderAction.&lt;/p&gt;

&lt;p&gt;RenderAction works like a mini-request, exercising the MvcHandler, but re-using the existing HttpContext.&amp;#160; It simulates a request, but writes out to the exact same response stream, at the exact right place:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_267CA1EA.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="267" alt="image" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jimmy_5F00_bogard/image_5F00_thumb_5F00_3780CFCD.png" width="721" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Our view doesn’t look much different, it looks like a cross between a Url.Action call and RenderPartial:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="background:#ffee62;"&gt;&amp;lt;%&lt;/span&gt; Html.RenderAction&amp;lt;&lt;span style="color:#2b91af;"&gt;LoginController&lt;/span&gt;&amp;gt;(c =&amp;gt; c.Widget()); &lt;span style="background:#ffee62;"&gt;%&amp;gt;

&lt;/span&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;View Products&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;What you &lt;em&gt;don’t&lt;/em&gt; see is any data or model passed to RenderAction.&amp;#160; The LoginController is a plain controller, with a regular action on it.&amp;#160; The action now can be concerned with both finding the data for the model and choosing the view to render:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LoginController &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Controller
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ViewResult &lt;/span&gt;Widget()
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;currentUser = _userSession.GetCurrentUser();

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;View(currentUser);
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I don’t have to jump through hoops to find where my information came from, as I only need to follow the link from the RenderAction call to the Widget action method.&amp;#160; Additionally, my original ProductController now has absolutely zero logic for all of the orthogonal concerns, whether it’s hidden in an action filter or not.&amp;#160; For each view, I can decide what master page to use, and place those RenderAction calls there.&amp;#160; I let my view decide what layout is correct.&lt;/p&gt;

&lt;p&gt;Wherever I see action filters poking around with ViewData, I see a very clear path to using RenderAction instead.&amp;#160; It’s a much more cohesive and flexible model, and straightforward to understand where each individual piece comes from.&amp;#160; Controllers have enough responsibility as it is, why do they need to be burdened with the additional responsibility of organizing data for tangential concerns?&amp;#160; RenderAction has zero performance penalty, as it’s not a real, external request.&amp;#160; ViewData can be abused as a bag-o’-stuff for views to consume, but that won’t lead to maintainable, understandable markup.&amp;#160; Instead, we can utilize the RenderAction method and create very cohesive controllers and strongly-typed views, with explicit concerns.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22198" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=lo1E7YJQTPs:pRz-njUs1Yc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=lo1E7YJQTPs:pRz-njUs1Yc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=lo1E7YJQTPs:pRz-njUs1Yc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=lo1E7YJQTPs:pRz-njUs1Yc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=lo1E7YJQTPs:pRz-njUs1Yc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/lo1E7YJQTPs" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22198</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/18/the-filter-viewdata-anti-pattern.aspx</feedburner:origLink></item><item><title>More on Late-Bound Invocations with Expression Trees</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/nqxVDC0qgms/more-on-late-bound-invocations-with-expression-trees.aspx</link><category>C#</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Wed, 17 Jun 2009 18:04:44 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22157</guid><description>&lt;p&gt;Recently, I went on a bit of a tear in the AutoMapper trying to improve performance.&amp;#160; Besides the threading issues I introduced (dictionary lookups are NOT thread safe, in case you’re wondering), I looked at improving the performance of the reflection piece of AutoMapper.&amp;#160; At its core, I map various kinds of MemberInfo objects on source types to MemberInfo objects on destination types.&amp;#160; The semantic model is a little more involved of course, but that’s the basic model of going from one complex type to another.&lt;/p&gt;  &lt;p&gt;I was quite dreading speeding up the reflection piece, not because IL generation and reflection emit isn’t interesting and all that, but it all looks quite ugly and hard to maintain.&amp;#160; Until I stumbled upon Nate Kohari’s post on &lt;a href="http://kohari.org/2009/03/06/fast-late-bound-invocation-with-expression-trees/"&gt;late-bound invocations via expression trees&lt;/a&gt;, I was avoiding that piece.&amp;#160; The basic idea is that expression trees, when compiled, are able to use regular reflection MemberInfo objects to generate the right IL at runtime to do what you normally do at compile time.&amp;#160; If you want a good sample of how to do IL, take a look at the expression tree compilation code in Reflector.&lt;/p&gt;  &lt;p&gt;His example worked great for methods, but AutoMapper also supports properties and fields.&amp;#160; To achieve the same result, I needed first to define a couple more delegate types to capture the kind of call you would do with fields and properties:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public delegate object &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LateBoundProperty&lt;/span&gt;(&lt;span style="color:blue;"&gt;object &lt;/span&gt;target);
&lt;span style="color:blue;"&gt;public delegate object &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LateBoundField&lt;/span&gt;(&lt;span style="color:blue;"&gt;object &lt;/span&gt;target);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Next, I just needed to create the expression tree for calling a field and property.&amp;#160; The property one is this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LateBoundProperty &lt;/span&gt;Create(&lt;span style="color:#2b91af;"&gt;PropertyInfo &lt;/span&gt;property)
{
    &lt;span style="color:#2b91af;"&gt;ParameterExpression &lt;/span&gt;instanceParameter = &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;object&lt;/span&gt;), &lt;span style="color:#a31515;"&gt;&amp;quot;target&amp;quot;&lt;/span&gt;);

    &lt;span style="color:#2b91af;"&gt;MemberExpression &lt;/span&gt;member = &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Property(&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Convert(instanceParameter, property.DeclaringType), property);

    &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LateBoundProperty&lt;/span&gt;&amp;gt; lambda = &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color:#2b91af;"&gt;LateBoundProperty&lt;/span&gt;&amp;gt;(
        &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Convert(member, &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;object&lt;/span&gt;)),
        instanceParameter
        );

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;lambda.Compile();
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I first create an expression that represents a call to a property (the MemberExpression instance).&amp;#160; Next, I need to wrap that MemberExpression call with a LambdaExpression, of type LateBoundProperty, so that I can execute the resulting delegate against any object I want.&amp;#160; The one for a field is quite similar:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LateBoundField &lt;/span&gt;Create(&lt;span style="color:#2b91af;"&gt;FieldInfo &lt;/span&gt;field)
{
    &lt;span style="color:#2b91af;"&gt;ParameterExpression &lt;/span&gt;instanceParameter = &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;object&lt;/span&gt;), &lt;span style="color:#a31515;"&gt;&amp;quot;target&amp;quot;&lt;/span&gt;);

    &lt;span style="color:#2b91af;"&gt;MemberExpression &lt;/span&gt;member = &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Field(&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Convert(instanceParameter, field.DeclaringType), field);

    &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LateBoundField&lt;/span&gt;&amp;gt; lambda = &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color:#2b91af;"&gt;LateBoundField&lt;/span&gt;&amp;gt;(
        &lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;.Convert(member, &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;object&lt;/span&gt;)),
        instanceParameter
        );

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;lambda.Compile();
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I still have a MemberExpression, but I use the Field method to create it instead.&amp;#160; It’s a little func-y looking, but here is what that above expression would look like, if I knew the target type at compile time:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Order&lt;/span&gt;, &lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt;&amp;gt; expr = o =&amp;gt; o.Total;&lt;/pre&gt;

&lt;p&gt;I have to jump through a few more hoops, as I don’t know the in and out times at compile time, it’s all stored as reflection information.&amp;#160; The expression tree building doesn’t care anyway, as the above lambda syntax is merely syntactic sugar for what we wrote earlier.&amp;#160; But how does this perform?&amp;#160; As &lt;a href="http://www.west-wind.com/weblog/posts/653034.aspx"&gt;Rick Strahl points out&lt;/a&gt;, it only makes sense after many iterations.&amp;#160; But I can then do fun things like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Order
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public decimal &lt;/span&gt;Total { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}

[&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Sample()
{
    &lt;span style="color:#2b91af;"&gt;PropertyInfo &lt;/span&gt;propertyInfo = &lt;span style="color:blue;"&gt;typeof &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Order&lt;/span&gt;).GetProperty(&lt;span style="color:#a31515;"&gt;&amp;quot;Total&amp;quot;&lt;/span&gt;);

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;lateBoundProperty = &lt;span style="color:#2b91af;"&gt;DelegateFactory&lt;/span&gt;.Create(propertyInfo);

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;order = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Order
        &lt;/span&gt;{
            Total = 50m
        };

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;total = lateBoundProperty(order);

    total.ShouldEqual(50m);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Since AutoMapper already has all of the reflection information cached on a per app-domain basis (that’s why you should only configure once), I can easily go through all of the reflected information and pre-compile all of the late-bound fields, properties and methods, so that they execute very fast during a mapping operation.&lt;/p&gt;

&lt;p&gt;So what’s the downside?&amp;#160; Startup is slower now, as it is CPU intensive to configure AutoMapper now.&amp;#160; But compared to the startup time of NHibernate and StructureMap in our applications, it does not add that much more to the total startup time.&amp;#160; Since we’re using AutoMapper in a web application, the we feel just as confident about its configuration time as we would NHibernate.&lt;/p&gt;

&lt;p&gt;Unfortunately, expression trees in .NET 3.0 do not support &lt;em&gt;setting&lt;/em&gt; fields and properties.&amp;#160; But since that’s changing in .NET 4.0, I think I’ll just wait to optimize the destination member assignment part of AutoMapper until then.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22157" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=nqxVDC0qgms:qLJcKwGDH3Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=nqxVDC0qgms:qLJcKwGDH3Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=nqxVDC0qgms:qLJcKwGDH3Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=nqxVDC0qgms:qLJcKwGDH3Q:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=nqxVDC0qgms:qLJcKwGDH3Q:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/nqxVDC0qgms" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22157</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/17/more-on-late-bound-invocations-with-expression-trees.aspx</feedburner:origLink></item><item><title>Why opinionated input builders for ASP.NET MVC?</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/X-WIxlczGiI/why-opinionated-input-builders-for-asp-net-mvc.aspx</link><category>ASP.NET MVC</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Mon, 15 Jun 2009 07:00:00 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22096</guid><description>&lt;p&gt;When we first started looking at crafting forms for MVC in a recent big project, we had just completed a ton of “view” screens for a wide variety of information.&amp;#160; Having learned quite a few things on crafting HTML on the view side, we had a few goals in mind to ensure that we improved our development experience on the edit side.&lt;/p&gt;  &lt;p&gt;But it wasn’t just the development experience we wanted to improve, it was the design/conception/analysis phase as well.&amp;#160; By centering our conversations around creating “inputs for” our view model, we could create a lot of consistency in our screens.&amp;#160; Our major goals for our opinionated builders were:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Input elements should look the same&lt;/li&gt;    &lt;li&gt;Common classes of input elements should look the same, so that enumerations are always in a drop-down, nullable enumerations are in a radio button group, date-times are in a special date and time template, etc.&lt;/li&gt;    &lt;li&gt;Our UI designers should not have to think about designing individual input elements&lt;/li&gt;    &lt;li&gt;Developers should not have to think about what the standard input element HTML is&lt;/li&gt;    &lt;li&gt;Everything rendered should work with ModelState, validation, and UI testing in a completely consistent, predictable and deterministic manner&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In many of the MVC examples out there, I see a metric ton of duplication around designing forms.&amp;#160; You always see the same “label” element, the input element, validation errors, asterisk for required fields, and so on copied over and over again for every single form element.&amp;#160; What a waste!&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Removing the duplication&lt;/h3&gt;  &lt;p&gt;What we saw was that if we gathered information from the strongly-typed expression, we could make an informed decision on what HTML to render.&amp;#160; Is your model member decorated with a required field attribute?&amp;#160; Render an asterisk.&amp;#160; Is the type of the member an enumeration?&amp;#160; Render a drop-down, but include all of the other normal input element business (label, etc.).&amp;#160; Is the type of the member a Guid?&amp;#160; Render a hidden field.&amp;#160; But funnel all of these decisions through a single call to a single method, “InputFor”.&lt;/p&gt;  &lt;p&gt;The benefit of opinionated input builders was that it was just one less design decision that had to be discussed and implemented, all the way through the process.&amp;#160; By employing rigorous standardization on our design, we could create a very consistent user experience.&lt;/p&gt;  &lt;p&gt;I don’t really see a panacea for a master opinion framework, as you’ll still have to decide what opinions are valid on &lt;em&gt;your&lt;/em&gt; project.&amp;#160; But ASP.NET MVC, like many other frameworks, is one that allows you to form your own opinions, without making any recommendations on its own.&amp;#160; Do make sure you form these opinions, as otherwise you’ll be stuck maintaining a lot of duplication of HTML and behavior in your views.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22096" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=X-WIxlczGiI:0R8Wh86hq6A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=X-WIxlczGiI:0R8Wh86hq6A:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=X-WIxlczGiI:0R8Wh86hq6A:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=X-WIxlczGiI:0R8Wh86hq6A:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=X-WIxlczGiI:0R8Wh86hq6A:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/X-WIxlczGiI" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22096</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/15/why-opinionated-input-builders-for-asp-net-mvc.aspx</feedburner:origLink></item><item><title>Requesting features for AutoMapper</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/w6OReKo4Mv8/requesting-features-for-automapper.aspx</link><category>AutoMapper</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Sun, 14 Jun 2009 18:08:09 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22095</guid><description>&lt;p&gt;On the &lt;a href="http://groups.google.com/group/automapper-users"&gt;AutoMapper mailing list&lt;/a&gt;, I get a lot of what I consider wacky requests.&amp;#160; Not because the requests aren’t valid, but rarely do I get any context of what people are trying to do with &lt;a href="http://automapper.codeplex.com/"&gt;AutoMapper&lt;/a&gt;.&amp;#160; As a reference, we are using AutoMapper in these situations:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Mapping from Domain/Presentation Model to ViewModel&lt;/li&gt;    &lt;li&gt;Mapping from Domain/Presentation Model to EditModel (forms) &amp;lt;- yes, different concerns at play here&lt;/li&gt;    &lt;li&gt;Mapping from Domain to a Reporting model (think printable view screens, not analytics)&lt;/li&gt;    &lt;li&gt;Mapping from EditModel forms to Command objects&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Some of the requests I’ve inferred include a lot of mapping from ViewModels &lt;em&gt;back&lt;/em&gt; to Domain models.&amp;#160; Personally, this seems wacky to me, unless you’re in some sort of ActiveRecord/CRUD scenario.&amp;#160; In those cases, I’d rather expose my model directly to my views.&lt;/p&gt;  &lt;p&gt;If AutoMapper doesn’t do what you want, a few things might be true:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;There is a bug&lt;/li&gt;    &lt;li&gt;You’re doing something valid, but in a scenario I haven’t encountered&lt;/li&gt;    &lt;li&gt;You’re doing something you shouldn’t do, and trying to attach two boards with a screw and a hammer&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Object-to-object mapping is a broad spectrum of distinct scenarios, and AutoMapper really only focuses on the scenarios where your destination type looks like your source type, plus some flattening.&amp;#160; So if you’d like a scenario to be supported by AutoMapper, two things would greatly help me:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Code showing a failing test&lt;/li&gt;    &lt;li&gt;Description of the context for which you’re trying to use it&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Context is &lt;strong&gt;very&lt;/strong&gt; helpful for me in the overall design, as only failing tests show me contrived, Foo to FooDto scenarios.&amp;#160; It helps if I understand at what place in your architecture you’re trying to use it, as it may not line up to how it was originally designed.&amp;#160; But context tells me if there is a broader concept at play, and I can design (or not) for that category of usage.&lt;/p&gt;  &lt;p&gt;Thanks again to everyone that has contributed, I’ve been consistently surprised by the number of feature requests that include a patch.&amp;#160; To date, I’ve received around 25 patches from the community, far exceeding any expectations I had.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22095" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=w6OReKo4Mv8:1jvjKcsBjqM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=w6OReKo4Mv8:1jvjKcsBjqM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=w6OReKo4Mv8:1jvjKcsBjqM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=w6OReKo4Mv8:1jvjKcsBjqM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=w6OReKo4Mv8:1jvjKcsBjqM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/w6OReKo4Mv8" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=22095</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/14/requesting-features-for-automapper.aspx</feedburner:origLink></item><item><title>Simplest versus first thing that could possibly work</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/tbePtWNRLbE/simplest-versus-first-thing-that-could-possibly-work.aspx</link><category>Design</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Wed, 10 Jun 2009 19:58:21 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21759</guid><description>&lt;p&gt;One of the core &lt;a href="http://www.xprogramming.com/xpmag/whatisxp.htm"&gt;XP practices&lt;/a&gt; that resonated with me quite early on was the concept of simple design.&amp;#160; When I learned TDD, this practice was further refined with the concept of doing the “simplest thing that could possibly work”.&amp;#160; To make a test pass, I would code the simplest thing that could possibly work.&amp;#160; It takes quite a bit of discipline to adhere to this mantra of simplicity, fighting a constant urge to design something more complex than the problem at hand requires.&lt;/p&gt;  &lt;p&gt;Browsing the XP wiki, you can find a lot of discussion of what exactly this means.&amp;#160; TDD calls for “Red, Green, Refactor”, which might lead you to wonder why you would need to refactor after doing the simplest thing that could possibly work.&amp;#160; It seems that the consensus formed around first performing the fewest steps, then refactoring to the fewest pieces or components.&amp;#160; But in our quest for simplicity, I notice a second, more subtle mistake: &lt;strong&gt;confusing the first thing that happens to work with the simplest thing that could possibly work&lt;/strong&gt;.&amp;#160; If I choose the first thing that happens to work, my refactoring step often leads me merely to the simplest solution, but not the most elegant.&lt;/p&gt;  &lt;p&gt;The difference between the two is easy to fix – it just requires thinking!&amp;#160; Thinking about possible solutions, different designs, vetting alternate paths to the goal.&amp;#160; This can be accomplished through pair programming, whiteboarding, and just about any exercise that requires us to think of at least two possible solutions before picking the winner.&amp;#160; I don’t necessarily see this happening with &lt;em&gt;every&lt;/em&gt; possible solution, however.&amp;#160; But some of the most awkward designs I’ve created seem to stem from just picking the first thing that works, and not doing a little thinking.&lt;/p&gt;  &lt;p&gt;Which is quite sad, as a little effort and investment in investigating multiple designs pays off many-fold in the long run.&amp;#160; Evolutionary design works best when we’re not stumbling in the dark, but making informed decisions with the most options as possible on the table.&amp;#160; If this sounds something like the idea of concurrent or &lt;a href="http://xp123.com/xplor/xp0611/index.shtml"&gt;set-based engineering&lt;/a&gt;, it should!&amp;#160; Except in this case, we perform it in the micro, at the point of every non-trivial design decision.&amp;#160; Simplicity is not automatic, and often comes from choosing the best design from a few options.&amp;#160; But we can’t be lazy about it, as taking just five minutes to think of a different approach can save man-hours (or days even) further down the road.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21759" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=tbePtWNRLbE:Almn7FAcUQs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=tbePtWNRLbE:Almn7FAcUQs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=tbePtWNRLbE:Almn7FAcUQs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=tbePtWNRLbE:Almn7FAcUQs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=tbePtWNRLbE:Almn7FAcUQs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/tbePtWNRLbE" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=21759</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/10/simplest-versus-first-thing-that-could-possibly-work.aspx</feedburner:origLink></item><item><title>Defining and refining conventions</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/6Sj2BrqUdAQ/defining-and-refining-conventions.aspx</link><category>Design</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Tue, 09 Jun 2009 06:35:34 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21661</guid><description>&lt;p&gt;At last night’s &lt;a href="http://adnug.org/"&gt;ADNUG&lt;/a&gt; talk, &lt;a href="http://codebetter.com/blogs/jeremy.miller/"&gt;Jeremy Miller&lt;/a&gt; talked about Convention over Configuration, and many of the principles the Rails community embraces.&amp;#160; He showed a few examples of opinionated software, such as FubuMVC.&amp;#160; One thing I would have liked more conversation around (but no time, alas), was the process of discovering conventions and forming the opinions that make up &lt;a href="http://gettingreal.37signals.com/ch04_Make_Opinionated_Software.php"&gt;opinionated software&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Opinionated software, as I see it, is a framework that provides intentionally chosen axes of change, where other axes are fixed to adhere to agreed-upon principles.&amp;#160; In Rails Active Record for example, by default my entity’s shape is whatever shape my table structure is, optimizing for very little configuration.&amp;#160; Because Ruby is a dynamic language, it can get away with this easily with meta-programming tricks.&lt;/p&gt;  &lt;p&gt;But how do we arrive at such opinions?&amp;#160; How do we decide which principles are acceptable, which are not?&amp;#160; Every design decision has a tradeoff, and frameworks like Rails aren’t going to satisfy everyone’s opinion.&amp;#160; We need some mechanism to form these opinions and craft our conventions.&lt;/p&gt;  &lt;h3&gt;Integrating evolutionary design&lt;/h3&gt;  &lt;p&gt;With our &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/03/fighting-technical-debt-with-the-wall-of-pain.aspx"&gt;wall of pain&lt;/a&gt;, we strive to ensure that we have one design vision.&amp;#160; Introduce a refactoring, and we want to retrofit and remove duplication everywhere.&amp;#160; Often, this is architectural duplication, such as the knowledge of a required field propagated throughout every layer in the system.&amp;#160; To eliminate this architectural duplication through conventions and opinions, it would likely take several iterations of that design before everyone is happy with the result.&lt;/p&gt;  &lt;p&gt;But the cost of propagating that design does have a real, tangible cost.&amp;#160; Iterating a design along with propagating it will cause a very real churn, even to the point where it could frustrate developers and discourage innovation.&amp;#160; On the flip side, iterating endlessly and never retrofitting our opinions leads to chaos, as well fall into the trap of having a hundred truths in our system, all of them correct at one point in time.&amp;#160; A new developer that came on recently vented his frustration with this problem, as he was spinning his wheels on an old design, simply because he picked the wrong version of the truth to model from.&lt;/p&gt;  &lt;p&gt;So we need to both iterate and propagate our design, ideally at key tipping points where we’ve arrived at a sound design, and no important unanswered questions remain.&amp;#160; We might have questions about our design, but answers might only come through applying our design in a variety of scenarios.&lt;/p&gt;  &lt;h3&gt;Past the tipping point&lt;/h3&gt;  &lt;p&gt;From my experience, these tipping points are fairly obvious, and follow Evans’ concept of breakthrough refactorings.&amp;#160; We make incremental enhancements, slowly improving our design over time.&amp;#160; At a critical mass of awareness of problems and understanding of the domain, we introduce a change that dramatically improves the design.&lt;/p&gt;  &lt;p&gt;These tipping points can’t be anticipated, nor can they be prognosticated.&amp;#160; In fact, trying to form opinions in absence of any context for these opinions is very likely to lead to awkward, friction-inducing development.&amp;#160; Another word for premature opinions might be BDUF.&lt;/p&gt;  &lt;p&gt;The middle ground here is one where we become finely attuned to the pain induced by our design, not try to invent problems where they don’t exist, iterate our design, and retrofit after each breakthrough.&amp;#160; Opinionated software is a fantastic concept, but we can’t confuse opinion formation with misguided attempts to make all design decisions upfront in the absence of agreeing upon the principles that led to the opinions.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21661" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=6Sj2BrqUdAQ:d6m5M3hL2Cw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=6Sj2BrqUdAQ:d6m5M3hL2Cw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=6Sj2BrqUdAQ:d6m5M3hL2Cw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=6Sj2BrqUdAQ:d6m5M3hL2Cw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=6Sj2BrqUdAQ:d6m5M3hL2Cw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/6Sj2BrqUdAQ" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=21661</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/09/defining-and-refining-conventions.aspx</feedburner:origLink></item><item><title>Reflecting reality</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/5VIIRJeFGhg/reflecting-reality.aspx</link><category>TDD</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Sun, 07 Jun 2009 20:18:09 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21607</guid><description>&lt;p&gt;Reading over the latest MSDN magazine issue, I’m always encouraged when I see something that I consider important on the cover, &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd882516.aspx"&gt;Test-Driven Design&lt;/a&gt;.&amp;#160; It covers one of the more difficult technical aspects of TDD, which is mock objects.&amp;#160; It took me a couple of years before I really understood the “right” way to use mocks as a design tool, and it wasn’t until I read the &lt;a href="http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Addison-Wesley/dp/0131495054"&gt;Meszaros book&lt;/a&gt; that the concept of direct and indirect inputs and outputs laid down simple rules for mock objects.&lt;/p&gt;  &lt;p&gt;The really strange thing about this article is that it uses NMock as its mock object library.&amp;#160; NMock?&amp;#160; Nothing against the library, but I can count at least two mocking frameworks that are more popular, Rhino Mocks and Moq.&amp;#160; From folks I talk to in the ALT.NET circles, it’s the vast majority of folks using Rhino Mocks, with a healthy following of Moq.&amp;#160; Folks using NMock are those stuck on older codebases, as NMock is (as far as I can tell) the earliest mocking framework for .NET.&amp;#160; It’s all well and good to show one mocking framework, if that’s the one you’re accustomed to, but to not even &lt;em&gt;mention&lt;/em&gt; the most popular mocking framework in .NET?&amp;#160; A little strange.&lt;/p&gt;  &lt;p&gt;So what’s the real issue?&amp;#160; Here’s some example code from the article:&lt;/p&gt;  &lt;pre class="code"&gt;[Test]
&lt;span style="color:blue;"&gt;public void &lt;/span&gt;ReceiptTotalForASaleWithNoItemsShouldBeZero()
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;receiptReceiver = mockery.NewMock&amp;lt;IReceiptReceiver&amp;gt;();
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;register = &lt;span style="color:blue;"&gt;new &lt;/span&gt;Register();
    register.NewSaleInitiated();

    Expect.Once.On(receiptReceiver).Method(&lt;span style="color:#a31515;"&gt;&amp;quot;ReceiveTotalDue&amp;quot;&lt;/span&gt;).With(0.00);

    register.SaleCompleted();
} &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This is frustrating, string-based mocks?&amp;#160; Here’s a fun TDD exercise, rename the ReceiveTotalDue method, and watch how many tests break for the wrong reason.&amp;#160; Tests should fail because of assertion failures, not because I renamed a method.&amp;#160; Additionally, the Arrange-Act-Assert syntax is nowhere to be found.&amp;#160; The AAA syntax made mocking fun, and for me, useful, as the record-replay model led to brittle, difficult to read tests.&lt;/p&gt;

&lt;p&gt;Digging deeper, it turns out that the article was written by a ThoughtWorker, and ThoughtWorks sponsors the development of NMock.&amp;#160; I’m glad that mocks got some love in MSDN, but I’d rather the article reflect today’s reality of using mocking frameworks.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21607" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=5VIIRJeFGhg:6lo8jSBdTxo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=5VIIRJeFGhg:6lo8jSBdTxo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=5VIIRJeFGhg:6lo8jSBdTxo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=5VIIRJeFGhg:6lo8jSBdTxo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=5VIIRJeFGhg:6lo8jSBdTxo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/5VIIRJeFGhg" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=21607</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/07/reflecting-reality.aspx</feedburner:origLink></item><item><title>Fighting technical debt with the wall of pain</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/jmDLidIS6YI/fighting-technical-debt-with-the-wall-of-pain.aspx</link><category>Agile</category><category>Refactoring</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Wed, 03 Jun 2009 17:57:39 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21489</guid><description>&lt;p&gt;Technical debt, even on the agile-ist of agilista teams, still accumulates.&amp;#160; Debt is inevitable, as initial design is always based on assumptions, not all of which pan out.&amp;#160; I never view that as a failure, as all we can do is make the best decision given the limited information we know at any given time.&amp;#160; Experience with DDD has shown me that often, design and architecture doesn’t undergo linear improvements.&amp;#160; Rather, we reach a critical mass of information and knowledge where it becomes plainly and painfully obvious that our current design will no longer suffice.&lt;/p&gt;  &lt;p&gt;In other situations, technical debt arises out of creating hidden forms duplication where only large-level, architectural refactorings can take the codebase to another level.&amp;#160; This duplication comes not necessarily from domain concepts, but structural concepts, or what I like to call the “application domain”.&amp;#160; We often need to create a model of our application, with things like the Command pattern, Strategy pattern and so on.&amp;#160; Breakthroughs in this area happen just as they do in our model of the problem domain, but instead arise out of use cases and the structure of our application, rather than from a deeper understanding of our problem domain.&lt;/p&gt;  &lt;p&gt;Finally, we have technical debt arising out of finding better ways of accomplishing the same result.&amp;#160; It could be a layer supertype, switching to a jQuery plugin, or just plain removing subtle copy-paste duplication.&amp;#160; Often, we see this last kind of technical debt arising out of larger teams, where individual frequency of duplication is rare, but project-wide duplication is far more pervasive.&amp;#160; For example, I might introduce subtle duplication around an area once every three weeks.&amp;#160; Because it is so sporadic, I don’t necessarily perceive the problem.&amp;#160; But if I have five other team members, the frequency of duplication might be three times per week, above the threshold for one developer’s perception.&lt;/p&gt;  &lt;p&gt;To tackle the inevitable growth of technical debt, we need some sort of strategy in place to address that risk.&lt;/p&gt;  &lt;h3&gt;Option #1 – Do nothing&lt;/h3&gt;  &lt;p&gt;Yes, the team might &lt;em&gt;say&lt;/em&gt; a lot, complaining and the like, but never do anything about it.&amp;#160; Or, they are simply not aware.&amp;#160; Ignorance, apathy or hopelessness, I’m quite sure this approach is not viable for applications that need to change.&lt;/p&gt;  &lt;p&gt;Or, the team has made management or the product team aware of a problem, but were unable to explain or justify the work required to fix the problem, so it merely lingers.&amp;#160; I’ve been in this option far too often in my career, and it’s never a fun feeling.&lt;/p&gt;  &lt;h3&gt;Option #2 – Cowboy style&lt;/h3&gt;  &lt;p&gt;In the absence of any form of technical story artifact, it’s up to the development team to prioritize technical debt payments, in the form of refactoring stories.&amp;#160; Outside of any strategy, prioritization and planning is often cowboy-style, done immediately when found, without regard to impact or other more important issues.&amp;#160; Refactorings are chosen based on how interesting it might be, the level of immediate frustration of the developer finding the duplication, or how easy the fix might seem.&lt;/p&gt;  &lt;p&gt;Most of the time, it’s done exactly when the fix is found, without much effort into analysis of the impact, cost or benefit of the fix.&amp;#160; Additionally, the fix is usually quite local, and not propagated to the rest of the system.&amp;#160; We might make it easier going forward working with a standard component, but all too often this new standard is not retrofitted back to the rest of the application.&amp;#160; This leads to multiple “right” ways of doing things, where the design of the next new component starts from the last component built, as long as we happen to remember what the last component was.&lt;/p&gt;  &lt;p&gt;This happened on a recent project, where we created a new layer supertype, and all new controllers needed to implement this new base class.&amp;#160; Unfortunately, this design was refined several times, until we had a half-dozen versions of the “right” way to design a controller.&lt;/p&gt;  &lt;p&gt;It’s quite enticing to cowboy-code technical debt fixes.&amp;#160; We, as the developer, get to play the hero type, announcing to the team “I fixed the Floogle problem!”.&amp;#160; It’s a good feeling, unless you’re met with blank stares and unspoken (or vocal) questions of “why did you waste time on &lt;em&gt;that&lt;/em&gt;?”&lt;/p&gt;  &lt;h3&gt;Option #3 – Wall of pain&lt;/h3&gt;  &lt;p&gt;Instead of fixing technical debt issues at the exact moment we encounter them, our team instead keeps a prioritized queue of technical debt items on our whiteboard.&amp;#160; On it, we track two sets of items:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Problems with a proposed solution&lt;/li&gt;    &lt;li&gt;Problems with no solution, and a plea for help&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As a contract to ourselves, we took an oath to not go forward with a new solution without retrofitting the application to use the new concept.&amp;#160; This ensured that we didn’t have pockets of bad code intermixed with good code, or worse, seven different designs in our system of the same concept.&amp;#160; The retrofitting was key for us to continue to innovate and improve, and let us find broader concepts.&amp;#160; The more examples we had of a concept, the more we could find commonality.&amp;#160; If there are seven ways to do the same thing in our system, there is just as much duplication, but a duplication that is much &lt;em&gt;much&lt;/em&gt; harder to both recognize and fix.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://khurwitz.blogspot.com/"&gt;Kevin&lt;/a&gt; and &lt;a href="http://jeffreypalermo.com/"&gt;Jeffrey&lt;/a&gt; teamed up to imbue in me a sense of pain-driven development.&amp;#160; The more something hurts, the more it needs to be fixed.&amp;#160; If local builds take 10 minutes, that’s a lot of pain throughout the day.&amp;#160; This concept led us to our current “wall of pain” that includes these items:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The problem&lt;/li&gt;    &lt;li&gt;The solution&lt;/li&gt;    &lt;li&gt;The level of pain (1-5)&lt;/li&gt;    &lt;li&gt;The estimate to retrofit, in points&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If something is very painful, but easy to fix, it is moved up on the list.&amp;#160; However, the effort to retrofit has to be a consideration, as it often indicates the risk introduced into our system of a large change.&amp;#160; Since a defined solution is part of this list, the point estimate is defined in terms of relative complexity, and therefore risk.&lt;/p&gt;  &lt;p&gt;For items without a solution, we just leave out the solution and estimate to retrofit.&amp;#160; These items are analyzed and given a solution as needed.&amp;#160; Many designs need vetting before established as the “new standard”, so our team will wait to pick a solution until we’re quite satisfied with the result. &lt;/p&gt;  &lt;p&gt;All of this assumes that technical debt items aren’t tracked in your normal taskboard/kanban/story wall.&amp;#160; Otherwise, you’ll likely have an established manner of prioritization.&lt;/p&gt;  &lt;p&gt;We’ve had our wall of pain up for a few months, and at the very least, it provided visibility and a way for us to communicate the day-to-day development pain we might face.&amp;#160; We still introduce minor fixes and technical debt payments during our iterations, without using the wall of pain, but these are of the small and completely obvious variety.&amp;#160; Still key is the concept of retrofitting, which we find greatly helpful in maintaining a consistent codebase.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21489" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=jmDLidIS6YI:peHKIkMK-_E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=jmDLidIS6YI:peHKIkMK-_E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=jmDLidIS6YI:peHKIkMK-_E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=jmDLidIS6YI:peHKIkMK-_E:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=jmDLidIS6YI:peHKIkMK-_E:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/jmDLidIS6YI" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=21489</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/03/fighting-technical-debt-with-the-wall-of-pain.aspx</feedburner:origLink></item><item><title>Meaning of life</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/DCdzm1CehOk/meaning-of-life.aspx</link><category>Misc</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Thu, 28 May 2009 18:48:48 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21308</guid><description>&lt;p&gt;Wolfram Alpha knows all:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://grabbagoftimg.s3.amazonaws.com/Wolfram.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;From &lt;a href="http://www.urbandictionary.com/define.php?term=omg"&gt;OMG&lt;/a&gt; to &lt;a href="http://www.urbandictionary.com/define.php?term=omfsm"&gt;OMFSM&lt;/a&gt;, we now move to OMWA.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21308" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=DCdzm1CehOk:MMCxlprjjMg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=DCdzm1CehOk:MMCxlprjjMg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=DCdzm1CehOk:MMCxlprjjMg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=DCdzm1CehOk:MMCxlprjjMg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=DCdzm1CehOk:MMCxlprjjMg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/DCdzm1CehOk" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=21308</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/05/28/meaning-of-life.aspx</feedburner:origLink></item><item><title>PTOM: Black-box analysis of legacy applications</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/06j4wGDjEVQ/ptom-black-box-analysis-of-legacy-applications.aspx</link><category>Legacy Code</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Wed, 27 May 2009 20:20:33 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21279</guid><description>&lt;p&gt;It seems like such a great situation, you’ve been tasked with replacing an old legacy system with a shiny new Web 3.0 AJAX-ified replacement.&amp;#160; It’s your chance for the limelight as the knight in shining armor to come charging in with a new system that will *surely* blow away the old one.&amp;#160; That is, until you get mired in the problem of requirements coming in of “make it work like the other system”.&lt;/p&gt;  &lt;p&gt;As a consultant, it can take quite a while to extract what “success” means, especially as you might have so many different roles with widely differing opinions of what the new system should do.&amp;#160; The CIO wants whatever the buzzword of the month is, probably SOA or “Services”.&amp;#160; The sales team wants something “frickin sweet” and “snazzy”, while the IT department likely hates your guts, as you’re replacing the system they built.&amp;#160; Talk to the people actually &lt;em&gt;using&lt;/em&gt; the existing system, and they probably hate it, but don’t want to change.&amp;#160; Listen solely to them and you’ll get another mainframe application, developed in .NET.&lt;/p&gt;  &lt;p&gt;With a large existing system, replacing what already exists can’t come in one fell swoop.&amp;#160; Often, you’ll need to carve out subsystems of functionality, each of which likely needed its own system to begin with.&amp;#160; I never fault the original developers of these systems, as many were built at least 10 years ago, some 20.&amp;#160; It’s hard to build an application to last 20 years, especially if your business grows beyond what anyone might have imagined.&lt;/p&gt;  &lt;p&gt;Back to replacing a legacy system, we have to understand what the existing Godillapp does.&amp;#160; Recently, I worked on a project to replace a large chunk of a huge legacy system.&amp;#160; Some stats of the existing codebase were:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;1 million lines of SQL&lt;/li&gt;    &lt;li&gt;1.2 million lines of COBOL….NET&lt;/li&gt;    &lt;li&gt;800K lines of VB.NET&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This system did &lt;em&gt;everything&lt;/em&gt; and was the lifeblood of a billion-dollar corporation.&amp;#160; Of course, it wasn’t a billion-dollar corporation when the system was first written 20 years ago, and “replaced” 5 years ago, but it did take the company a long way.&amp;#160; As a part of this experience, we gained a few nuggets and strategies for dealing with these types of engagements in the future, and what follows is a list of those lessons learned.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Lesson #1 – What it does versus how it’s used&lt;/h3&gt;  &lt;p&gt;When we talked to various people about this application, we encountered two different stories.&amp;#160; One was from stakeholders who created the application, and one was from the people who used it.&amp;#160; The people who created it could tell us exactly what the application did.&amp;#160; They talked about major areas, features, database tables, screens and so on.&lt;/p&gt;  &lt;p&gt;But one thing was missing – how did people &lt;em&gt;use&lt;/em&gt; the system?&amp;#160; For that, we talked to the actual end users.&lt;/p&gt;  &lt;p&gt;Which showed a completely different story.&amp;#160; There was a lot of “&lt;a href="http://bill-poole.blogspot.com/2008/05/swivel-chair-integration-is-bad.html"&gt;swivel chair&lt;/a&gt;” integration going on, and users’ cubicles were covered in little post-it notes, cheat sheets and reference guides to serve as a living instruction manual.&amp;#160; Does that customer have a discount?&amp;#160; Well, put a note in the order comments field so that Cheryl in accounting remembers to note that in the invoice.&amp;#160; These insights into end-user behavior gave us knowledge that merely looking at the application, code and database would have obscured and even misled.&amp;#160; This, combined with input from all stakeholders, along with vision of where the company wanted the application to go, gave us direction into the system we needed to build.&lt;/p&gt;  &lt;p&gt;But we still needed to replicate existing functionality.&lt;/p&gt;  &lt;h3&gt;Lesson #2 – Craft your own story of the data&lt;/h3&gt;  &lt;p&gt;The application’s database was about the most interesting I’d ever seen.&amp;#160; It was ported from a mainframe, pretty much straight over.&amp;#160; This meant:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Lots of fixed-width columns&lt;/li&gt;    &lt;li&gt;No referential integrity&lt;/li&gt;    &lt;li&gt;Evolving architectural style&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For the core tables, we might have OLD_NMNG_OF_CLMNS, where as new tables followed tbl_hungarian notation.&amp;#160; To get around this, we exported the schema into an entirely new database, and created associations between tables as we found them.&amp;#160; We didn’t bother with all of the original columns, just associations, so that we could understand what related to what.&amp;#160; We couldn’t modify the existing database, but a playground of just the schema let us create reference diagrams of the “real” relationships of the tables.&lt;/p&gt;  &lt;p&gt;Next, we created searchable schema.&amp;#160; We created a table that included:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Database name&lt;/li&gt;    &lt;li&gt;Table name&lt;/li&gt;    &lt;li&gt;Column name&lt;/li&gt;    &lt;li&gt;Column data type&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Yes, I know this was available from the schema views, but we needed something that was super simple to query from.&amp;#160; With a system of hundreds and hundreds of tables, it helped to do things like “SELECT * FROM dbSchema WHERE colname LIKE ‘%PRODUCT_NUM%’”.&amp;#160; We didn’t know what was related to a product, but we could make an educated guess.&amp;#160; Since the original database had zero foreign key constraints and thousands of stored procedures, we needed to be able to take large guesses of how data was related to each other.&amp;#160; Existing developers might be able to give us direction, but with a system this big, we could only really rely on the actual system.&lt;/p&gt;  &lt;h3&gt;Lesson #3 – The data don’t lie&lt;/h3&gt;  &lt;p&gt;This one’s from the phrase “&lt;a href="http://www.urbandictionary.com/define.php?term=ball%20don%27t%20lie"&gt;ball don’t lie&lt;/a&gt;”.&amp;#160; You come to the business owners and ask, “what shipping codes do we need to support?”.&amp;#160; The answer is “all of them”.&amp;#160; There aren’t that many shipping services in the world, yet you find a hundred different ship codes in the database lookup table.&amp;#160; Do you really need to support all of these shipping codes?&amp;#160; Probably not.&lt;/p&gt;  &lt;p&gt;But to answer this, we need to gather more information on what these values mean.&amp;#160; Are some of these just test shipping codes that some developer put in the system six years ago?&amp;#160; Are some for obsolete shipping methods?&amp;#160; Again, we turned to analyzing the existing data.&amp;#160; It took a long time to run this batch process (around 4 hours), but we crafted another table that contained:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Column name&lt;/li&gt;    &lt;li&gt;Column value&lt;/li&gt;    &lt;li&gt;Number of occurrences&lt;/li&gt;    &lt;li&gt;Percentage of total&lt;/li&gt;    &lt;li&gt;Last date of value&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Essentially, we would group a table by a column, one by one, gathering statistics on how much each value was used, and when it was last used.&amp;#160; This gave us the hard data that said, “see that code ‘OC4’? It was last used 5 years ago, and only twice”.&amp;#160; With that information, we could dive in to the original database, and find that the person who created these orders was “Cosmo Kramer”.&amp;#160; With this information, we could figure out exactly what kinds of things we needed to support.&lt;/p&gt;  &lt;p&gt;Additionally, we were able to provide hard data on who used what features.&amp;#160; We might find a certain shipping code used only 100 times, a fraction of the total, but these were used by one of the company’s biggest customers, so it suddenly jumped in importance.&amp;#160; It was still the customer who decided what to support, but we were able to give them a much, much better picture of the data than many of their seasoned veterans did not know.&lt;/p&gt;  &lt;p&gt;If you can’t run a big batch data mining process against the database, I suggest you learn two SQL techniques: the GROUP BY clause, and derived tables.&amp;#160; The general idea is to first create an inner query where you group by values, and then an outer query that performs additional grouping and statistics.&amp;#160; This gives you quick information like “what percentage of total orders used the OC4 shipping code?”&amp;#160; Very useful information for decision makers.&lt;/p&gt;  &lt;h3&gt;Lesson #4 – Profile, profile, profile&lt;/h3&gt;  &lt;p&gt;In a codebase that’s large enough, debugging code is counterproductive.&amp;#160; Instead, we can take the route of poking an application on one side, and seeing what comes out the other, while listening in to the conversation using a SQL profiler (or network profiler).&amp;#160; In this manner, we can do things like add a line item to an order, and see how the application performs that operation.&amp;#160; In one example, we added a single line item to an order and over 280 queries executed to perform that one operation.&lt;/p&gt;  &lt;p&gt;We might find common stored procedure names, and go back the code armed with a textual search to see exactly what code was executed.&amp;#160; While the SQL codebase had over a million lines, profiling told us that only a fraction of this was actually used.&amp;#160; Because there was no database change management system in place, we saw a hundred different sprocs to retrieve an order.&amp;#160; Instead of using an existing sproc, it was easier just to create a new one.&lt;/p&gt;  &lt;p&gt;As we profiled more and more, we combined this knowledge back into our metadata database, adding comments to what the purpose of each table was.&amp;#160; The list of “important” tables was eventually whittled down to what you might expect, and many were just a bunch of features that never panned out, cancelled projects and so on.&amp;#160; With all of our information, we could almost look backwards in time to see the entire history of the company.&lt;/p&gt;  &lt;h3&gt;Lesson #5 – Dump the negativity&lt;/h3&gt;  &lt;p&gt;Although it’s easy to trash-talk the existing system, it won’t make you any friends with the existing IT folks.&amp;#160; No one likes having their baby called ugly, even it fell off the ugly tree and hit every branch on the way down.&amp;#160; You don’t know the political situations for the last 20 years, nor the different forces at play.&amp;#160; These systems put a lot of food on a lot of people’s plate, but no longer help the company grow.&amp;#160; The only thing you can criticize is a failure to recognize when the existing system no longer matches the company’s needs.&amp;#160; Other than that, best to keep positive, stay focused on delivering value, and just *quietly* make notes for future Daily WTF contributions.&lt;/p&gt;  &lt;h3&gt;Wrapping it up&lt;/h3&gt;  &lt;p&gt;Replacing a legacy system is costly and risky.&amp;#160; Anyone involved with projects like these can attest to the frequency of failures in this arena.&amp;#160; But armed with a well-thought out strategy, we can maximize the possibility of success.&amp;#160; Nothing’s guaranteed of course, but at the very least, we’ll have vastly increased the knowledge of the existing system.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21279" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=06j4wGDjEVQ:3sguE3dcR3Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=06j4wGDjEVQ:3sguE3dcR3Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=06j4wGDjEVQ:3sguE3dcR3Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=06j4wGDjEVQ:3sguE3dcR3Y:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=06j4wGDjEVQ:3sguE3dcR3Y:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/06j4wGDjEVQ" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=21279</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/05/27/ptom-black-box-analysis-of-legacy-applications.aspx</feedburner:origLink></item><item><title>Subverting TDD as a design tool</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/iEsVYgbs1rk/subverting-tdd-as-a-design-tool.aspx</link><category>TDD</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">bogardj</dc:creator><pubDate>Fri, 22 May 2009 06:29:45 PDT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:21160</guid><description>&lt;p&gt;So TypeMock can now &lt;a href="http://blog.typemock.com/2009/05/mockingfaking-datetimenow-in-unit-tests.html"&gt;mock DateTime.Now&lt;/a&gt;.&amp;#160; Replacing the functionality of DateTime.Now, which is an external dependency, was one of the first issues that taught me the value of TDD.&amp;#160; With TypeMock replacing DateTime.Now, I get all the benefits of unit testing, but none of the benefits of TDD.&amp;#160; Yes, my code is now “testable” in the sense that I can now write a unit test against my code, but I’m using Jedi mind-tricks to do so.&lt;/p&gt;  &lt;p&gt;TDD combines example-driven, client-first development with the icing of providing a safety net of providing executable specifications to lock down existing behavior.&amp;#160; For me, the real benefit of TDD is the former, much more than the latter.&amp;#160; TDD tells me exactly where my design is bad, as tests that are hard to write belie a design that is hard to work with.&lt;/p&gt;  &lt;p&gt;When I first hit the “DateTime.Now” problem, TDD led me down a path that forced me to invert dependencies.&amp;#160; Instead of an opaque dependency on DateTime.Now, I had an explicit relationship between that class and its dependency through an IClock interface:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;PunchClock(&lt;span style="color:#2b91af;"&gt;ISystemClock &lt;/span&gt;clock)&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;From the standard external system dependencies such as clock, files, configuration and so on, I’ve used the dependency inversion principle everywhere inside my codebase.&amp;#160; Why?&amp;#160; TDD and DIP tell me if my class is doing too much.&amp;#160; If my class is doing too much, it will be hard to understand, change and maintain.&amp;#160; In my experience, TDD is by far the most efficient tool at showing me deficiencies in my design.&amp;#160; It shows me not only problems in design of individual members and even type and member names, but problems of my overall architecture.&lt;/p&gt;

&lt;p&gt;If I have a legacy system I need to change, there’s a &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052"&gt;whole book on techniques&lt;/a&gt; for doing so in a safe, responsible manner.&amp;#160; Changing legacy code is like camping – you always leave your campsite cleaner than when you found it.&amp;#160; But I still can’t understand why I would need a tool that subverts all of the indicators in a unit test of bad design.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=21160" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=iEsVYgbs1rk:Q61MvBL0u10:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=iEsVYgbs1rk:Q61MvBL0u10:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=iEsVYgbs1rk:Q61MvBL0u10:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=iEsVYgbs1rk:Q61MvBL0u10:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=iEsVYgbs1rk:Q61MvBL0u10:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/iEsVYgbs1rk" height="1" width="1"/&gt;</description><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/jimmy_bogard/rsscomments.aspx?PostID=21160</wfw:commentRss><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/05/22/subverting-tdd-as-a-design-tool.aspx</feedburner:origLink></item></channel></rss>
