<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://codebetter.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jeremy D. Miller -- The Shade Tree Developer</title><link>http://codebetter.com/blogs/jeremy.miller/default.aspx</link><description>Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>The Videos for NDC 2009 are online</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/07/01/the-videos-for-ndc-2009-are-online.aspx</link><pubDate>Wed, 01 Jul 2009 16:16:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:249515</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=249515</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/07/01/the-videos-for-ndc-2009-are-online.aspx#comments</comments><description>&lt;p&gt;The links to the videos recorded for NDC 2009 talks are online and linked in &lt;a href="http://www.ndc2009.no/agenda.aspx?cat=1071&amp;amp;id=1813&amp;amp;day=3726"&gt;the agenda pages here&lt;/a&gt;.&amp;nbsp; My talks are at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://media01.smartcom.no/Microsite/start.aspx?eventid=4484"&gt;Lessons Learned from a Long Lived Codebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://media01.smartcom.no/Microsite/start.aspx?eventid=4464"&gt;Presentation Patterns for Composite Applications&lt;/a&gt; (I&amp;#39;d dearly appreciate feedback from folks on this talk)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://media01.smartcom.no/Microsite/start.aspx?eventid=4532"&gt;Convention over Configuration applied to .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://media01.smartcom.no/Microsite/start.aspx?eventid=4528"&gt;Software Design and Testability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=249515" width="1" height="1"&gt;</description></item><item><title>Talking conventions with the Hanselman</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/27/talking-conventions-with-the-hansleman.aspx</link><pubDate>Sat, 27 Jun 2009 15:22:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:249336</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=249336</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/27/talking-conventions-with-the-hansleman.aspx#comments</comments><description>&lt;p&gt;Scott Hanselman &lt;a href="http://hanselminutes.com/default.aspx?showID=185"&gt;posted a podcast he &amp;amp; I recorded at NDC&lt;/a&gt; last week.&amp;nbsp; We nominally talked about applying conventions and opinionated software to .Net, then we went off on every possible tangent that presented itself.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=249336" width="1" height="1"&gt;</description></item><item><title>NDC 2009 Wrapup</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/24/ndc-2009-wrapup.aspx</link><pubDate>Wed, 24 Jun 2009 12:58:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:249262</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=249262</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/24/ndc-2009-wrapup.aspx#comments</comments><description>&lt;p&gt;I&amp;rsquo;m on my way back from the &lt;a href="http://www.ndc2009.no/en/"&gt;Norwegian 
Developer&amp;rsquo;s Conference&lt;/a&gt; in Oslo this past week.&amp;nbsp; I had a fantastic time 
meeting some new people, hanging out with friends, interacting with a couple 
heroes, and seeing a little bit of Norway.&amp;nbsp; Special thanks to &lt;a href="http://andersnoras.com/"&gt;Anders Nor&amp;aring;s&lt;/a&gt; for inviting me to NDC.&amp;nbsp; I had a 
blast with the Bergen gang:&amp;nbsp; &lt;a href="http://blog.fohjin.com/"&gt;Mark Nijhof&lt;/a&gt;, 
&lt;a href="http://twitter.com/stclairjohn"&gt;John St Clair&lt;/a&gt;, and &lt;a href="http://blog.torresdal.net/"&gt;Jon Arild T&amp;oslash;rresdal&lt;/a&gt;.&amp;nbsp; I got to put a face 
to &lt;a href="http://andreasohlund.blogspot.com/"&gt;Andreas &amp;Ouml;hlund&lt;/a&gt; who is 
developing the StructureMap integration with WCF and nServiceBus.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I think all the talks were recorded and are going to be posted to the NDC 
website for download.&amp;nbsp; I&amp;rsquo;ll blog the links as soon as they go up.&amp;nbsp; I gave 8 
talks in 4 days across 2 cities.&amp;nbsp; I&amp;rsquo;m not sure I want to be one of those 
professional speakers that do that a couple dozen times a year.&amp;nbsp; I had an 
awesome crowd for my &amp;ldquo;Design and Testability&amp;rdquo; talk that I appreciated.&amp;nbsp; I had a 
comparatively small crowd for my &amp;ldquo;Conventions over Configuration&amp;rdquo; talk, but I 
had a lot of good questions afterwards that probably made that my favorite 
session of the week.&amp;nbsp; Most importantly, I presented some preliminary design 
patterns work on the &amp;ldquo;Screen Activation Lifecycle&amp;rdquo; from my book and I thought it 
went over pretty well (you can see a little preview of it on &lt;a href="http://neverindoubtnet.blogspot.com/2009/06/screen-factory.html"&gt;Ward 
Bell&amp;rsquo;s blog here&lt;/a&gt;).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I got even more book ideas from &lt;a href="http://jonas.follesoe.no/"&gt;Jonas 
Folles&amp;oslash;&amp;rsquo;s&lt;/a&gt; talk.&amp;nbsp; &amp;lt;bias&amp;gt;Apparently there are some crazy people out 
there who think it&amp;rsquo;s not entirely insane to do &amp;ldquo;View First&amp;rdquo; navigation.&amp;nbsp; I need 
to cover that pattern in the book and pretend it&amp;rsquo;s not a nutso thing to 
do.&amp;lt;/bias&amp;gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Lastly, I gave my &amp;ldquo;Lessons Learned from StructureMap&amp;rdquo; talk one more time.&amp;nbsp; I 
think I&amp;rsquo;m going to retire this one permanently, so I might try to blog it out 
over the next 2 months.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Upon reflection, I think my favorite thing about NDC was that there was a lot 
of more or less ALT.NET-ish content (and the older speakers from the bigger 
software world that we admire), but we weren&amp;rsquo;t in special camps or the &amp;ldquo;Agile 
gutter&amp;rdquo; track like in the DevTeach&amp;rsquo;s I went to a couple years ago.&amp;nbsp; I love that 
the tee shirts for the conference said &amp;ldquo;Legalize Unit Testing.&amp;rdquo;&amp;nbsp; I don&amp;rsquo;t ever 
see ALT.NET becoming completely the mainstream, but it&amp;rsquo;d be nice to stop being 
this strangely alternative stuff on the fringe.&lt;/p&gt;
&lt;p&gt;I got ambushed by Hanselman and &lt;a href="http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-Storyteller-with-Jeremy-Miller/"&gt;recorded 
for Channel 9&lt;/a&gt; spouting off on 3 hours sleep about &amp;ldquo;Executable Requirements&amp;rdquo;, 
StoryTeller, apologizing for using angle brackets, and explaining why I&amp;rsquo;m not 
using Oslo/MGrammar for creating external DSL&amp;rsquo;s for testing (hint:&amp;nbsp; I&amp;rsquo;m very 
unenthusiastic about the phrase &amp;ldquo;you just have to parse the AST&amp;rdquo;).&amp;nbsp; There&amp;rsquo;s 
several other impromptu recordings from the &lt;a href="http://channel9.msdn.com/tags/HanselminutesOn9/"&gt;speaker&amp;rsquo;s area 
here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All in all, I had a great time and I&amp;rsquo;d be happy to recommend NDC next year 
for those of you in that part of the world.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=249262" width="1" height="1"&gt;</description></item><item><title>Dogfooding</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/10/dogfooding.aspx</link><pubDate>Wed, 10 Jun 2009 14:57:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:248368</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=248368</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/10/dogfooding.aspx#comments</comments><description>&lt;p&gt;For the most part, I try to dogfood all new versions and flavors of StructureMap and StoryTeller at Dovetail.&amp;nbsp; Just in case my boss reads this, that&amp;#39;s largely okay because all of StoryTeller and many StructureMap enhancements are built for Dovetail to begin with.&amp;nbsp; Today I hit an issue with the brand new &amp;quot;Nested Container&amp;quot; feature in the StructureMap trunk.&amp;nbsp; Here&amp;#39;s a rundown of the basic timeline this morning:&lt;/p&gt;
&lt;p&gt;4:55 PM Last Night:&amp;nbsp; StackOverflowException&lt;/p&gt;
&lt;p&gt;9:10 AM:&amp;nbsp; I isolate the problem to StructureMap itself as a nested Container is getting disposed&lt;/p&gt;
&lt;p&gt;9:12 AM:&amp;nbsp; I think to myself that dogfooding sucks&lt;/p&gt;
&lt;p&gt;9:15 AM:&amp;nbsp; I&amp;#39;m very, very glad that I caught this error before users&lt;/p&gt;
&lt;p&gt;9:55 AM:&amp;nbsp; After standup, I finally look at the offending method and say to myself &amp;quot;I&amp;#39;m a f***ing idiot&amp;quot; because I KNEW that what I did was going to cause a StackOverflow and I forgot to write the guard clause&lt;/p&gt;
&lt;p&gt;9:57 AM:&amp;nbsp; Fixed and happy&lt;/p&gt;
&lt;p&gt;10:04 AM:&amp;nbsp; Blowing off steam by writing this blog post&lt;/p&gt;
&lt;p&gt;10:05 AM:&amp;nbsp; Playing Centipede while my checkin dance gets going&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thank you for listening, I feel better now.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=248368" width="1" height="1"&gt;</description></item><item><title>A Quiet Milestone</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/09/a-quiet-milestone.aspx</link><pubDate>Tue, 09 Jun 2009 13:59:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:248328</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=248328</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/09/a-quiet-milestone.aspx#comments</comments><description>&lt;p&gt;I wouldn&amp;#39;t read too much into this, but while I was giving my talk at the Austin .Net User&amp;#39;s Group last night I asked the crowd how many people were doing some form of Agile or just plain iterative development.&amp;nbsp; Almost every hand in the room went up.&amp;nbsp; I&amp;#39;m sure not everyone is doing it well (I&amp;#39;m not sure that we do it well), but the numbers were still staggering to me.&amp;nbsp; Sometime in 2005 &lt;a href="http://www.lostechies.com/blogs/stevedonie/"&gt;Steve Donie&lt;/a&gt; and I did a talk at ADNUG on Continuous Integration and as I recall, only one bunch of people in the entire room was using CI.&amp;nbsp; Unscientifically, a lot of stuff has changed over the past 4-5 years.&amp;nbsp; I like that we spend more time now on how to do Agile (or Lean) development better instead of the same boring discussions about whether this new Agile thing can really work.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=248328" width="1" height="1"&gt;</description></item><item><title>Convention over Configuration at ADNUG on Monday the 8th</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/03/convention-over-configuration-at-adnug-on-monday-the-8th.aspx</link><pubDate>Wed, 03 Jun 2009 16:45:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:248017</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=248017</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/03/convention-over-configuration-at-adnug-on-monday-the-8th.aspx#comments</comments><description>&lt;p&gt;For all of you in Austin or thereabouts, I&amp;#39;ll be speaking this &lt;a href="http://adnug.org/June09"&gt;coming Monday at Adnug&lt;/a&gt; on &amp;quot;&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419655.aspx"&gt;Conventions over Configuration&lt;/a&gt;.&amp;quot;&amp;nbsp; I hope to see you there (and at Rudy&amp;#39;s afterwards).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=248017" width="1" height="1"&gt;</description></item><item><title>Yes, I'm going to finish "Build Your Own CAB" (sorta)</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/01/yes-i-m-going-to-finish-quot-build-your-own-cab-quot-sorta.aspx</link><pubDate>Mon, 01 Jun 2009 20:29:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:246853</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=246853</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/06/01/yes-i-m-going-to-finish-quot-build-your-own-cab-quot-sorta.aspx#comments</comments><description>&lt;p&gt;Over the past couple years I&amp;#39;ve received quite a bit of positive feedback on my &amp;quot;&lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the-build-your-own-cab-series-table-of-contents.aspx"&gt;Build Your Own CAB&lt;/a&gt;&amp;quot; series on design patterns for building desktop applications. Unfortunately, a lot of the feedback is &amp;quot;&lt;b&gt;it&amp;#39;d be really nice if you&amp;#39;d get around to finishing the series&lt;/b&gt;.&amp;quot;&amp;nbsp; After all, I didn&amp;#39;t really publish anything that actually related to building composite applications.&amp;nbsp; I am wrapping up this series plus quite a bit more (+ incorporating the work that Martin Fowler already did on these topics but didn&amp;#39;t publish), but as part of a book for Addison Wesley tentatively entitled &amp;quot;Presentation Patterns.&amp;quot;&amp;nbsp; I&amp;#39;ll try to blog a lot more about the book next month as I shift to working on it a lot more.&amp;nbsp; I&amp;#39;m strictly focusing on design patterns rather than any particular technology.&amp;nbsp; At a guess, I&amp;#39;d say that half of the samples will be C#/WPF and the rest will be Java, WinForms, and even a couple JavaScript samples.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the rough outline at the moment.&amp;nbsp; If there&amp;#39;s something you&amp;#39;d particularly like to see more or less of, feel free to comment on this (please).&lt;/p&gt;
&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;What&amp;rsquo;s so hard about
     building a User Interface?&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Look at everything
      that&amp;rsquo;s going on here&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;How do I test this?&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;How do I connect
      all this together?&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Separated
     Presentation&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;The travails of
      using Active View&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;The Humble &lt;span class="yshortcuts" id="lw_1243890793_0"&gt;Dialog
      Box&lt;/span&gt; (narrative)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Separated
      Presentation (narrative)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;GUI Architectures
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Passive View&lt;span&gt;&amp;nbsp; &lt;/span&gt;(pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Supervising
      Controller (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Presentation Model
      (Model-View-ViewModel) (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Communication
      between the View and Presenter (narrative)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="MsoNormal" style="margin-left:1.5in;"&gt;&lt;span style="font-family:Arial;"&gt;&lt;span&gt;&lt;span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;i.&lt;span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;By events&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-left:1.5in;"&gt;&lt;span style="font-family:Arial;"&gt;&lt;span&gt;&lt;span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;ii.&lt;span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-size-adjust:none;font-stretch:normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;Direct communication&lt;/span&gt;&lt;/p&gt;
&lt;ol style="margin-top:0in;"&gt;
&lt;li&gt;&amp;nbsp;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;What&amp;rsquo;s the Model?
      (long narrative)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Model Based
      Validation with the Notification Pattern&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;&lt;span class="yshortcuts" id="lw_1243890793_1"&gt;The Mechanics&lt;/span&gt; of the
     View&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Managing Screen State (narrative)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Flow
      Synchronization (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Observer Synchronization
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Flattener (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;MicroControllers
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Embedded Controller
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Screen&lt;/span&gt;&lt;span style="font-family:Arial;"&gt; State&lt;/span&gt;&lt;span style="font-family:Arial;"&gt; (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Complex Screens&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Composite
      Controller (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Layout (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;The Application Shell&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Coordination
      between Screens (narrative)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Screen Activation
      Lifecycle (narrative)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;&lt;span style="border-bottom:1px dashed #0066cc;cursor:pointer;" class="yshortcuts" id="lw_1243890793_2"&gt;Presenter First &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt; (narrative)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Application Shell&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Application
      Controller&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Screen Collection&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Screen Subject&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Layer SuperType&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Event Coordination&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Coordination
      between Screens&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Latch (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Event &lt;span class="yshortcuts" id="lw_1243890793_3"&gt;Aggregator&lt;/span&gt;
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Command (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Crafting a Domain
     Specific Language (not well defined yet, but could be a great chapter)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Modularity&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Using an Inversion
      of Control Tool&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Bootstrapper
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Registry (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Presentation Chooser (pattern)&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Communicating with
     the Server&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Message Bus&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Command Executor
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;&lt;span style="background:transparent none repeat scroll 0% 0%;cursor:pointer;" class="yshortcuts" id="lw_1243890793_4"&gt;Automated Testing&lt;/span&gt;&lt;/span&gt;&lt;ol style="margin-top:0in;"&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;&lt;span style="background:transparent none repeat scroll 0% 0%;cursor:pointer;" class="yshortcuts" id="lw_1243890793_5"&gt;Unit testing&lt;/span&gt; the
      Presenter layer&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Unit testing the
      View&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Subcutaneous
      Testing&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Strategies for User
      Interface Testing&lt;/span&gt;&lt;/li&gt;
&lt;li class="MsoNormal"&gt;&lt;span style="font-family:Arial;"&gt;Screen Driver
      (pattern)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Oh, and my take on &amp;quot;is M-V-VM the same thing as Presentation
Model?&amp;quot;&amp;nbsp; I say yes.&amp;nbsp; I think it&amp;#39;s the exact same pattern just described
differently by Fowler and the Microsoft guys.&amp;nbsp; Think Leipzig and Sir
Isaac Newton discovering Calculus at the same time.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=246853" width="1" height="1"&gt;</description></item><item><title>Persistence Patterns:  Cascading Updates</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/30/persistence-patterns-cascading-updates.aspx</link><pubDate>Sat, 30 May 2009 21:34:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:243398</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=243398</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/30/persistence-patterns-cascading-updates.aspx#comments</comments><description>&lt;p&gt;This content was cut from my most recent MSDN article on Persistence Patterns for length and possibly quality.&amp;nbsp; What the heck, it&amp;#39;s an important topic that throws some people off and it&amp;#39;s also something that many people who are new to ORM&amp;#39;s frequently don&amp;#39;t understand.&amp;nbsp; I&amp;#39;m also misusing the term &amp;quot;reachability&amp;quot; a bit here, so substitute &amp;quot;cascading save&amp;quot; wherever that term pops in.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;








 
  Normal
  0
  
  
  
  
  false
  false
  false
  
  EN-US
  X-NONE
  X-NONE
  
   
   
   
   
   
   
   
   
   
   
   
  
  
   
   
   
   
   
   
   
   
   
   
   
  

 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 





&lt;p class="MsoNormal"&gt;Many persistence tools support cascading updates and deletes through an object graph.&amp;nbsp; This is
both a powerful tool for improved productivity and a source of confusion and
errors. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;To explain this concept, let&amp;rsquo;s imagine that we&amp;rsquo;re building a
new invoicing system that has an Invoice class like this one:&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// The Invoice
class is purposely simplified&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// for this
example&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Invoice&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;InvoiceLine&lt;/span&gt;&amp;gt;
Lines { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;;
}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Customer&lt;/span&gt; Customer { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;
&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;line-height:115%;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The Invoice class has a list of InvoiceLine objects and a
&amp;ldquo;many-to-one&amp;rdquo; reference to a Customer object.&lt;span&gt;&amp;nbsp;
&lt;/span&gt;When our new invoicing system receives a message directing it to enter a
new Invoice, our system creates a new Invoice object, all the related
InvoiceLine objects, and assigns the proper &lt;b&gt;existing&lt;/b&gt; Customer object to our new Invoice.&lt;span&gt;&amp;nbsp; &lt;/span&gt;That process is shown in the CreateInvoice()
method of the InvoiceService class shown below:&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;InvoiceService&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt;
&lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IUnitOfWork&lt;/span&gt;
_unitOfWork;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;
InvoiceService(&lt;span style="color:#2b91af;"&gt;IUnitOfWork&lt;/span&gt; unitOfWork)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_unitOfWork = unitOfWork;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;NewInvoiceConfirmation&lt;/span&gt; CreateInvoice(&lt;span style="color:#2b91af;"&gt;NewInvoiceMessage&lt;/span&gt; message)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:green;"&gt;// Read in
the NewInvoiceMessage object, create &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// the
children InvoiceLine objects,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// and
attach an existing Customer object&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Invoice&lt;/span&gt;
invoice = buildInvoiceHeader(message);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;invoice.Lines =
buildInvoiceLines(message);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;invoice.Customer =
lookupExistingCustomer(message);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//
Persist the new invoice&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_unitOfWork.MarkNew(invoice);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// Commit
the transaction&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_unitOfWork.Commit();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt;
buildConfirmation(invoice);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;line-height:115%;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In order to finish the new Invoice transaction, we need to
save the header information for the Invoice object, the reference from the new
Invoice to the existing Customer, and each of the individual InvoiceLine
objects.&lt;span&gt;&amp;nbsp; &lt;/span&gt;However, in the code above for
the InvoiceService.CreateInvoice() method we &lt;b&gt;only marked the top Invoice object as a new object&lt;/b&gt; in our Unit of
Work.&lt;span&gt;&amp;nbsp; &lt;/span&gt;That&amp;rsquo;s because we&amp;rsquo;re depending on
our persistence tool to use a cascading update policy to walk the Invoice
structure and save all the new InvoiceLine objects at the same time.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In my last article I talked about using Object Relational
Mapping to create a persistence solution by configuring a mapping between the
object model and the database structure.&lt;span&gt;&amp;nbsp;
&lt;/span&gt;For the Invoice class in our new invoicing system, I would configure the
mapping from Invoice like this (using Fluent NHibernate):&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;InvoiceMap&lt;/span&gt; :
&lt;span style="color:#2b91af;"&gt;ClassMap&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Invoice&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;
InvoiceMap()&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// The
Cascade.All() directive forces NHibernate&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// to
save the InvoiceLine children of an Invoice&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// object
whenever the Invoice object is saved&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HasMany&amp;lt;&lt;span style="color:#2b91af;"&gt;InvoiceLine&lt;/span&gt;&amp;gt;(x
=&amp;gt; x.Lines).Cascade.All();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// The
Cascade.None() directive tells NHibernate&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// NOT to
save the Customer object when&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// the
Invoice is saved.&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// The
link from Invoice to Customer will be persisted&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;References(x =&amp;gt;
x.Customer).Cascade.None();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;line-height:115%;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In this example, we&amp;rsquo;ve made the InvoiceLine children of an
Invoice object &amp;ldquo;reachable&amp;rdquo; when a new Invoice object is saved.&lt;span&gt;&amp;nbsp; &lt;/span&gt;In the case of our new invoicing system, I&amp;rsquo;m
assuming that new Invoices can only be created for existing Customer objects.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Because the Customer object isn&amp;rsquo;t modified by
creating a new Invoice, we certainly don&amp;rsquo;t want the Customer object saved (or
even checked by our persistence tool for possible modifications) when a new
Invoice object is saved.&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Because of the potential for errors due to incorrect
assumptions about how cascading updates are configured, my strong advice is to
use a battery of integration tests against your service layer to ensure that
data is persisted correctly.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Tightening
up the rules and policies for cascading inserts, saves, and deletes is a common
way to optimize the performance of a system that uses Object Relational Mapping
for persistence.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Again, this
optimization process will be much safer if it is supported by automated tests
that can catch regression errors caused by changing &amp;ldquo;reachability&amp;rdquo; rules.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Lastly, almost every business application of any size that
we build will contain hierarchical information.&lt;span&gt;&amp;nbsp;
&lt;/span&gt;Reachability is another great example of how an ORM persistence tool can
save development time versus old fashioned &amp;ldquo;hand-rolled&amp;rdquo; data access code.&lt;span&gt;&amp;nbsp; In this case, NHibernate is dealing with running the insert, update, or delete statements in the correct order and dealing with moving the new autonumber Id&amp;#39;s from the parent to the children records.&amp;nbsp; Believe it or not, I do know how to write that ADO.Net code from scratch and even how to write sproc&amp;#39;s to do the data access, but call me lazy and shiftless &amp;#39;cause I&amp;#39;d rather just go _unitOfWork.Save( myNewInvoice ) or _unitOfWork.Delete( myOldInvoice ) and get on with the next feature.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=243398" width="1" height="1"&gt;</description></item><item><title>More Persistence Patterns in MSDN</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/29/more-persistence-patterns-in-msdn.aspx</link><pubDate>Fri, 29 May 2009 15:01:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:241359</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=241359</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/29/more-persistence-patterns-in-msdn.aspx#comments</comments><description>&lt;p&gt;EDIT:&amp;nbsp; I missed something the first time around.&amp;nbsp; If some persistence tool makes it so that I can only put business logic in my domain models using a partial class, that&amp;#39;s an automatic FAIL!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My latest article in the Patterns in Practice column is in the June edition of MSDN Magazine.&amp;nbsp; This time around I continued the discussion about persistence patterns with the &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd882510.aspx"&gt;Unit of Work Pattern and some (very watered down) discussion about Persistence Ignorance&lt;/a&gt;.&amp;nbsp; Granted, this isn&amp;#39;t my favorite article I&amp;#39;ve ever written, but these are important topics that I think everyone needs to consider as part of their persistence strategy.&amp;nbsp; For you folks out there that say &amp;quot;bah, humbug, I don&amp;#39;t need no POCO,&amp;quot; I think you need to at least consider the issues before you blow it off.&lt;/p&gt;
&lt;p&gt;To summarize, *I* think Persistence Ignorance is important for these reasons in descending order of importance (you can argue whether 3, 4, or 5 is more important):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Can I exercise my business logic and user interface without having to drag in the database?&amp;nbsp; This is crucial for &lt;b&gt;efficient&lt;/b&gt; unit testing.&amp;nbsp; With the way the Entity Framework v1 did lazy loading, the answer is no.&amp;nbsp; With NHibernate and maybe EF v4, the answer is yes.&lt;/li&gt;
&lt;li&gt;Can I design my object structure and database model independently?&amp;nbsp; In other words, don&amp;#39;t make the &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/02/23/Don_2700_t-Let-the-Database-Dictate-Your-Object-Model.aspx"&gt;database model dictate the shape of the object model&lt;/a&gt;.&amp;nbsp; As the complexity of the system grows beyond dirt simple, codegen&amp;#39;ing the object model from the database tables is teh suck.&lt;/li&gt;
&lt;li&gt;How easy is it to make small incremental or evolutionary changes to my domain model?&amp;nbsp; Again, I think code generation schemes that start from a complete database model and generate the object model are optimized for BDUF and become unwieldy in the face of small changes.&amp;nbsp; Solutions that require change tracking to be coded directly into the domain model make incremental changes harder because of the extra weight of changing or adding new properties to the model.&lt;/li&gt;
&lt;li&gt;What strictures does my persistence tooling place on my object model?&amp;nbsp; Marking properties as virtual just to enable lazy loading is annoying.&amp;nbsp; Having to expose public properties of inner collections like Lists or Sets destroys encapsulation and is completely unacceptable to me.&amp;nbsp; My persistence tool shouldn&amp;#39;t force me to compromise encapsulation.&amp;nbsp; I really don&amp;#39;t want to have to inherit from a base class in the framework.&amp;nbsp; It&amp;#39;s very valuable to use my own Layer Supertype for my domain model rather than blowing my one superclass on infrastructure goo.&lt;/li&gt;
&lt;li&gt;Lastly, I don&amp;#39;t want persistence methods cluttering up the public interface of my domain model classes.&amp;nbsp; Interface Segregation Principal baby!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the record, it does look like from a shallow reading that the new EF v4 looks much better than EF v1 did -- but still falls well short of NHibernate.&amp;nbsp; It all depends on how much you really care about this stuff.&amp;nbsp; *I* care deeply about the ability to design continuously and incrementally, clean separation of concerns, and test driven development.&amp;nbsp; To me, the object model is the main player in the application and the database is nothing but a persistence mechanism.&amp;nbsp; If you don&amp;#39;t care about those things, or are just simply too engrained in data centric orthodoxy to change, then you can happily ignore that list.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Go ahead and argue away I suppose.&amp;nbsp; I&amp;#39;m offline for the next 3-4 days, so you automatically get the last word in;)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=241359" width="1" height="1"&gt;</description></item><item><title>The Joys and Pains of a Long Lived Codebase -- The Video</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/28/the-joys-and-pains-of-a-long-lived-codebase-the-video.aspx</link><pubDate>Thu, 28 May 2009 13:57:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:239947</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=239947</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/28/the-joys-and-pains-of-a-long-lived-codebase-the-video.aspx#comments</comments><description>&lt;p&gt;InfoQ just posted the &lt;a href="http://www.infoq.com/presentations/Lessons-Learned-Jeremy-Miller"&gt;video from my talk&lt;/a&gt; at QCon San Francisco 2008. In this talk I went over some of the harsh lessons I learned from 5+ years of working with the StructureMap code, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How classic &amp;quot;Big Noun&amp;quot; classes grew out of control and how moving to more role-centered abstractions has made the code easier to extend&lt;/li&gt;
&lt;li&gt;How badly expressed unit tests impaired progress and why I finally believe in BDD&lt;/li&gt;
&lt;li&gt;Creating an API that serves the end user instead of the internal model of the framework&lt;/li&gt;
&lt;li&gt;How our expectations for using a framework have changed very dramatically in the last 5 years&lt;/li&gt;
&lt;li&gt;The coding and design flaws that made the code harder to change&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#39;ll be giving an updated version of this talk at NDC 2009 in a couple weeks as well.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=239947" width="1" height="1"&gt;</description></item><item><title>Looking at 6 month old code...</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/13/looking-at-6-month-old-code.aspx</link><pubDate>Wed, 13 May 2009 19:36:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:224223</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=224223</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/13/looking-at-6-month-old-code.aspx#comments</comments><description>&lt;p&gt;...and I&amp;#39;m not horrified (much) at what I&amp;#39;m seeing.&amp;nbsp; Is it:&lt;/p&gt;
&lt;p&gt;A.) That the code is really okay&lt;/p&gt;
&lt;p&gt;B.) I haven&amp;#39;t learned anything new in the past 6 months&lt;/p&gt;
&lt;p&gt;C.) I just haven&amp;#39;t looked hard enough&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;UPDATE:&amp;nbsp; As we learned in school from our experiences with standardized testing, &lt;b&gt;the answer is always &amp;quot;C!&amp;quot;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And finally, I wonder how much more blogging there&amp;#39;s going to be today &amp;#39;cause Twitter is down?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=224223" width="1" height="1"&gt;</description></item><item><title>Sneek Peek at StoryTeller (i.e. my FitNesse killer for .Net)</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/11/sneek-peek-at-storyteller-i-e-my-fitnesse-killer-for-net.aspx</link><pubDate>Mon, 11 May 2009 19:20:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:222370</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=222370</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/11/sneek-peek-at-storyteller-i-e-my-fitnesse-killer-for-net.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve gotten pinged 4-5 times in the past week about just where I&amp;#39;m at with StoryTeller development.&amp;nbsp; I think I&amp;#39;m finally closing in on something that I could release at least as a preview.&amp;nbsp; Just to prove that I&amp;#39;m still working on it, here&amp;#39;s a sneek preview of the tool.&amp;nbsp; I&amp;#39;m tentatively doing another Elegant Code Cast with David Starr on StoryTeller soon, so just pile on with any questions.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Quick History&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve had a love/hate relationship with NFit and/or FitNesse for quite some time.&amp;nbsp; In many ways, I still believe that &amp;quot;&lt;a href="http://www.agilemodeling.com/essays/executableSpecifications.htm"&gt;Executable Specifications&lt;/a&gt;&amp;quot; are the &amp;quot;Holy Grail&amp;quot; of Agile/Lean software development and that belief naturally led me to using first NFit and then FitNesse.&amp;nbsp; However, I increasingly found FitNesse rather painful to use and impossible to transition to client teams.&amp;nbsp; My frustration with FitNesse eventially led me to start &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2006/10/17/Announcing-_2200_StoryTeller_2200_-_2D00_-A-new-.Net-tool-for-FIT-test-management.aspx"&gt;a new OSS project called StoryTeller&lt;/a&gt; as a replacement for the test editing and management functionality of FitNesse, but keeping the underlying Fit engine.&amp;nbsp; I coded on that for about 2 years with no more than middling enthusiasm and minimal success before I finally &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/08/12/why-i-m-suddenly-down-on-fit-fitnesse.aspx"&gt;threw my hands up in the air over the FitNesse&lt;/a&gt; testing engine and junked the whole StoryTeller project.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The New StoryTeller&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Late last year I started a complete &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/10/11/storyteller-is-dead-long-live-storyteller.aspx"&gt;ground up rewrite of StoryTeller&lt;/a&gt; with a totally different testing engine that we&amp;#39;re using to write acceptance tests and integration tests at Dovetail.&amp;nbsp; I haven&amp;#39;t made an official release yet, but as of right now StoryTeller has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A testing engine that is a superset of the basic FitNesse Fixture types (ColumnFixture, RowFixture, DoFixture, ArrayFixture, etc.).&amp;nbsp; The engine supports a mix of flow-based and table-based testing.&lt;/li&gt;
&lt;li&gt;Customizable type coercion&lt;/li&gt;
&lt;li&gt;A command line runner for use in an automated build&lt;/li&gt;
&lt;li&gt;A way to tag tests as either &amp;quot;Acceptance&amp;quot; or &amp;quot;Regression&amp;quot; for testing lifecycle (Regression test failures cause a build failure, Acceptance test failures are simply reported)&lt;/li&gt;
&lt;li&gt;A User Interface tool that acts as a runner and an interactive tool for test editing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How does this relate to other tools?&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NUnit/MbUnit/xUnit.Net -- There is some overlap, but an xUnit test will never be terribly readable to non coders, and that&amp;#39;s what StoryTeller is striving for.&amp;nbsp; I see xUnit tools being used for unit tests, StoryTeller for acceptance testing, and integration testing being a gray area where you might go either way on a case by case basis.&lt;/li&gt;
&lt;li&gt;FitNesse -- I obviously think StoryTeller is a far superior tool to FitNesse, or I&amp;#39;d just be using that as is.&amp;nbsp; FitNesse is the closest analogue to StoryTeller.&lt;/li&gt;
&lt;li&gt;Machine.Spec or Cucumber or RSpec -- Kind of solves the same problems in very different ways, but StoryTeller is more geared towards integrated acceptance testing.&amp;nbsp; I wouldn&amp;#39;t care to use StoryTeller for straight up TDD at the low level.&amp;nbsp; I guess the short answer on this comparison is &amp;quot;I don&amp;#39;t know.&amp;quot;&lt;/li&gt;
&lt;li&gt;Oslo -- One of the frequent examples of Oslo I&amp;#39;ve seen is a DSL over the top of WatiN for web testing -- and that&amp;#39;s great, but how about being able to quickly churn out little one off testing DSL&amp;#39;s?.&amp;nbsp; In many ways StoryTeller is a tool for creating External DSL&amp;#39;s for testing your application code.&amp;nbsp; That&amp;#39;s a direct overlap with Oslo (depending on which Oslo team member is speaking and to what audience), but at this time I feel like Oslo would require far more effort than StoryTeller in order to build a &lt;b&gt;behavioral, runtime DSL&lt;/b&gt; to do testing.&amp;nbsp; StoryTeller grammars allow you to quickly bridge the gap between how you want to express your test specifications and the system under test.&amp;nbsp; Oslo would require you to parse and interpret those nasty, nasty AST&amp;#39;s to perform the actual functionality.&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The Main Screen:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/InitialScreen.jpg"&gt;&lt;img style="border:0;" src="http://codebetter.com/resized-image.ashx/__size/900x0/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/InitialScreen.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Woohoo!&amp;nbsp; You can see all of the tests, you&amp;#39;ve got a status bar to show you what&amp;#39;s running, what&amp;#39;s queued up, and when the StoryTeller UI picked up the binaries (it does use a FileSystemWatcher like NUnit to watch for the system under test binary getting updated).&lt;/p&gt;
&lt;p&gt;At the top, you have options to filter the tests shown in the test tree on the left:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/FilterOptions.jpg"&gt;&lt;img src="http://codebetter.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/FilterOptions.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Uh, and if that looks a lot like the ReSharper unit test runner, let&amp;#39;s say that imitation is the sincerest form of flattery.&lt;/p&gt;
&lt;p&gt;You can also control the testing runtime like so:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/ExecutionOptions.jpg"&gt;&lt;img src="http://codebetter.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/ExecutionOptions.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;m particularly proud of these features.&amp;nbsp; Sometimes (most always), an integrated test can be slow to execute or Selenium can hang or who knows what can happen.&amp;nbsp; StoryTeller will allow you to specify that tests should be aborted the first time they encounter an exception or a test failure instead of running the entire test as it normally does.&amp;nbsp; You can also change the test timeout on the fly.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;StoryTeller can show you the tests that are queued up to execute:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Queue1.jpg"&gt;&lt;img src="http://codebetter.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Queue1.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yes, that screen is butt ugly so far, but it gives you the ability to track progress, clear tests out of the queue if you change your mind about running them, and abort the executing test.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Lastly, how about an actual test?&amp;nbsp; Here&amp;#39;s the preview mode:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Preview.jpg"&gt;&lt;img src="http://codebetter.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Preview.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and the Results mode:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Results.jpg"&gt;&lt;img src="http://codebetter.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Results.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Like I said, this is just a sneak peek.&amp;nbsp; I&amp;#39;ll have much more information out soon as I feel it&amp;#39;s becoming usable.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And no, I don&amp;#39;t think my problems with FitNesse are a team structure or a communication problem.&amp;nbsp; Please don&amp;#39;t insult my intelligence (again) by changing the subject.&amp;nbsp; The problem with FitNesse is mechanical.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=222370" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/StoryTeller/default.aspx">StoryTeller</category></item><item><title>Revitalizing a Technical Career</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/05/revitalizing-a-technical-career.aspx</link><pubDate>Tue, 05 May 2009 15:21:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:215282</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>21</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=215282</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/05/05/revitalizing-a-technical-career.aspx#comments</comments><description>&lt;p&gt;A good friend of mine recently asked my how he might go about revitalizing his career.&amp;nbsp; I&amp;#39;m putting some words in his mouth here, but I&amp;#39;m pretty sure that he&amp;#39;s interested in getting back into hands on development and moving away from a strictly managerial role.&amp;nbsp; In his case, he is/was a very strong developer who really just needs to scrape off the rust.&amp;nbsp; The problem is that I think he needs to go get some knowledge and experience to position him for a different role that he probably can&amp;#39;t get in his current role.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Here&amp;#39;s my thoughts on the subject.&amp;nbsp; I (and my friend) would appreciate some feedback and better ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pursue the MCP/MCSD certification.&amp;nbsp; I would definitely take certification into account when hiring very junior developers, but it&amp;#39;s not something that I would pay a lot of attention to for mid level or senior developers.&amp;nbsp; I think the certification effort could be helpful for experienced developers moving into a new platform where you just need to map Java names/syntax to C# names/syntax or vice versa, but the question is my mind is whether or not another effort would be better.&lt;/li&gt;
&lt;li&gt;Follow some of the leading blogs just to see what people are doing, thinking, and writing about.&amp;nbsp; For the cutting edge in .Net practice, I like &lt;a href="http://www.lostechies.com/"&gt;Los Techies&lt;/a&gt;, &lt;a href="http://elegantcode.com/"&gt;Elegant Code&lt;/a&gt;, and CodeBetter (of course).&amp;nbsp; For development in general, my favorite online source now is &lt;a href="http://infoq.com"&gt;InfoQ.com&lt;/a&gt;.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;I think podcasts can do a much better job of explaining/discussing subjects because of the more interactive nature.&amp;nbsp; My favorites are Herding Code and the Elegant Code cast.&amp;nbsp; DotNetRocks is by far the most popular, but I don&amp;#39;t think they cover their topics sometimes as well as some of the others.&amp;nbsp; Hanselminutes has some gems here and there.&amp;nbsp; The ALT.NET podcast just isn&amp;#39;t regular enough, but it&amp;#39;s good as long as it isn&amp;#39;t a meta-ALT.NET podcast (like the one I did last time).&lt;/li&gt;
&lt;li&gt;Go to user group meetings.&amp;nbsp; The talks themselves aren&amp;#39;t usually very good, but the conversations afterwards are worth it.&amp;nbsp; I prefer discussion groups like the NYC eXtreme Tuesday club and Austin&amp;#39;s ATX lunch group over eyes forward ***NUG meetings.&amp;nbsp; If you ever get a chance to attend an open spaces event, jump on it.&lt;/li&gt;
&lt;li&gt;You gotta get some experience with the newer things and concepts. My strongest recommendation to bump up your coding skills is to find a way to participate in an OSS project of some sort.&amp;nbsp; That recommendation goes double if you&amp;#39;re in some sort of non-Agile shop and you want to get some hands on experience with things like TDD and test automation.&amp;nbsp; Plus, OSS work is usually more interesting and much more challenging than the day to day programming (my experience anyway).&lt;/li&gt;
&lt;li&gt;Build a side project of some sort.&amp;nbsp; This is based on the theory that hands on experience is better than just reading.&amp;nbsp; Use different tools and techniques than your day job.&lt;/li&gt;
&lt;li&gt;Personally, when we&amp;#39;re hiring, I&amp;#39;m far more interested in a person&amp;#39;s
understanding of concepts and principles rather than in specific
technologies.&amp;nbsp; I would strongly recommend focusing much more on design principles and even practices as opposed to purely technical subjects.&amp;nbsp; If you study and build an understanding of the SOLID principles, you&amp;#39;ll be able to apply that knowledge to any enterprise software project.&amp;nbsp; Reading a book on WPF is useless for working on a web developement project.&amp;nbsp; I&amp;#39;m not saying to completely ignore technologies, just to put them at a lower priority.&lt;/li&gt;
&lt;li&gt;I honestly can&amp;#39;t think of a &lt;b&gt;single&lt;/b&gt; book to read that is going to make a huge difference.&amp;nbsp; I like the Pragmatic Programmer book, all of Fowler&amp;#39;s books, and the Feathers book, but I see books as a good supplement and not the main thing.&lt;/li&gt;
&lt;li&gt;Find a different job.&amp;nbsp; Maybe this isn&amp;#39;t a good recommendation during a deep recession, but your ability to grow in your career sometimes is only as good as your company.&amp;nbsp; I see a depressing number of people trying to rise above the riff raff at very mediocre development shops.&amp;nbsp; Sometimes you can make a big difference where you&amp;#39;re at, but other times you&amp;#39;re just stunting your growth.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;What I Did&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/07/08/what-i-ve-already-done-to-be-a-better-developer.aspx"&gt;I&amp;#39;ve written about this subject before&lt;/a&gt;, but a bit of a recap can&amp;#39;t hurt.&amp;nbsp; In 2002 I was moved into a non-coding architect role and I hated it.&amp;nbsp; At the time I only had experience with DNA technologies and Oracle when the enterprise development world was quickly being divided up into J2EE and .Net camps.&amp;nbsp; I felt like my career was circling the drains with every powerpoint I delivered and every bureaucratic meeting I attended.&amp;nbsp; I slowly started working on what became StructureMap off to the side to get some demonstrable experience with .Net and some new concepts (TDD, OOP).&amp;nbsp; In &amp;#39;03 I made the big leap out of the stultified big corporate IT world into ThoughtWorks right as Agile/XP was getting off the ground.&amp;nbsp; I spent a lot of time around stronger developers who were passionate about the craft of software development and learned a lot about software engineering (which I hadn&amp;#39;t in a CMMI wannabe shop because that was someone else&amp;#39;s job).&amp;nbsp; I can&amp;#39;t say that my experience there was roses every day, but I would credit that move with salvaging my career and putting me on a better path.&lt;/p&gt;
&lt;p&gt; The best single thing I&amp;#39;ve ever done for myself was to &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/01/25/should-i-blog.aspx"&gt;start blogging and writing&lt;/a&gt;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=215282" width="1" height="1"&gt;</description></item><item><title>My Quick Oversimplified ASP.Net MVC Pros and Cons</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/04/24/my-quick-oversimplified-asp-net-mvc-pros-and-cons.aspx</link><pubDate>Sat, 25 Apr 2009 00:03:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:202306</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>19</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=202306</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/04/24/my-quick-oversimplified-asp-net-mvc-pros-and-cons.aspx#comments</comments><description>&lt;p&gt;There&amp;#39;s been a lot bouncing back and forth about whether the ASP.Net MVC (and the MVC manner of building web apps in general) is a good thing or not.&amp;nbsp; I&amp;#39;d propose summing it up in two bullet points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;CON:&amp;nbsp; &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2009/04/24/is-asp-net-mvc-a-half-baked-solution.aspx"&gt;The ASP.Net MVC framework *is* half baked&lt;/a&gt;.&amp;nbsp; It isn&amp;#39;t usefully opinionated in the slightest other than it more or less promotes the MVC/Model 2 pattern, it encourages way too much sloppy &amp;quot;magic string&amp;quot; antipattern violations, it doesn&amp;#39;t have squat out of the box in terms of the &amp;quot;M&amp;quot; or helpful conventions on par with Rails, nothing like Capistrano (that might be changing soon though), and the Html helper libraries out of the box are just plain weak (I don&amp;#39;t like their approach for the MVC Futures either.&amp;nbsp; It&amp;#39;ll make the MVC more friendly to WebForms folks, but has the exact same problems as the current helpers).&amp;nbsp; In my opinion, &lt;b&gt;the MVC framework is not efficient unless you&amp;#39;re willing to roll up your sleeves and build your own project specific infrastructure&lt;/b&gt; to fill in the &amp;quot;M&amp;quot;, achieve some better testability, easier screen synchronization, and more productive Html helpers like what &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/04/24/how-we-do-mvc.aspx"&gt;Jimmy Bogard describes here&lt;/a&gt;.&amp;nbsp; If the thought of rolling your own NHibernate or &amp;quot;validation framework of your choice&amp;quot; integration with the MVC framework fills you with dread, then I don&amp;#39;t think you&amp;#39;re gonna want to use the MVC -- and that isn&amp;#39;t something to be ashamed about.&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;PRO:&amp;nbsp; &lt;b&gt;It&amp;#39;s pretty easy and straightforward to take the MVC framework by the horns and customize it for your benefit&lt;/b&gt;.&amp;nbsp; Granted, I felt like we hit a wall with the MVC framework at Dovetail and moved on to the FubuMVC efforts, but many of the things we&amp;#39;ve done that have enabled the most productivity for us are perfectly applicable to the MVC framework out of the box.*&amp;nbsp; I think that a lightweight application framework that&amp;#39;s specific to the application being built will almost always be more productive than a big, giant heavyweight &amp;quot;one size fits all&amp;quot; generic framework.&amp;nbsp; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To sum it up, I think the MVC (and any MVC framework for that matter) framework is a tool that maximizes the effectiveness of development teams that are willing and able to use creative solutions, but at this time doesn&amp;#39;t do much to help average teams who only code with what comes out of the box.&amp;nbsp; I&amp;#39;d also say that the &amp;quot;To MVC or not to MVC&amp;quot; argument is a classic example of the &amp;quot;&lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/01/16/Safety-versus-Power.aspx"&gt;Safety versus Power&lt;/a&gt;&amp;quot; argument.&amp;nbsp; I stand behind the assertion that the ASP.Net MVC framework is a better way in the end to build web apps than an &amp;quot;&lt;a href="http://codebetter.com/blogs/rob.conery/archive/2009/04/22/i-spose-i-ll-just-say-it-you-should-learn-mvc.aspx"&gt;abstraction wrapped in deception covered in lie sauce presented on a plate full of diversion and sleight of hand&lt;/a&gt;,&amp;quot;&amp;nbsp; but at this point it&amp;#39;s probably a tool strictly for early adopter type folks.&lt;/p&gt;
&lt;p&gt;Oh, and I don&amp;#39;t really want Microsoft to be the ones creating the more robust, opinionated stacks on top of the MVC framework anyway.&amp;nbsp; I&amp;#39;d much rather see the community build the specific integrations and application stacks because we have more freedom to choose tooling than an internal Microsoft effort, and some level of diversity is a good thing.&amp;nbsp; Microsoft putting out the official, comprehensive MVC solution could easily be a disaster that completely chokes off any further innovation.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;* I think we hit the wall with the MVC out of the box mostly because of the Thunderdome Principle and a convention based presentation chooser model for alternative browsers (we swap views and sometimes the presenter and view if the browser is on a mobile device).&amp;nbsp; We also tie the controller registration directly to the route configuration to eliminate errors (another shortcoming of the MVC framework IMHO).&amp;nbsp; At that point we found that the MVC controller lifecycle was simply too limiting for what we were trying to do and frankly wasn&amp;#39;t that hard to completely replace.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=202306" width="1" height="1"&gt;</description></item><item><title>See you at NDC 2009 in Oslo</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2009/04/23/see-you-at-ndc-2009-in-oslo.aspx</link><pubDate>Thu, 23 Apr 2009 14:23:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:201436</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/rsscomments.aspx?PostID=201436</wfw:commentRss><comments>http://codebetter.com/blogs/jeremy.miller/archive/2009/04/23/see-you-at-ndc-2009-in-oslo.aspx#comments</comments><description>&lt;p&gt;For those of you in that part of the world, I&amp;#39;ll be speaking at the &lt;a href="http://www.ndc2009.no/en/"&gt;Norwegian Developers Conference&lt;/a&gt; in Oslo, Norway on June 17-19, 2009.&amp;nbsp; It&amp;#39;s an incredible lineup taken straight from the author names on my programming bookshelf with a pretty decent ALT.NET lineup as well.&amp;nbsp; For my part, I&amp;#39;m speaking on:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Lessons Learned from a Long Lived Codebase -- What I&amp;#39;ve learned from 5+ years of building and rebuilding StructureMap to do new things and old things better&lt;/li&gt;
&lt;li&gt;Presentation Patterns for Composite Applications -- Advanced patterns.&amp;nbsp; Event aggregation, controlling the screen activation lifecycle, extensibility through using an IoC tool, creating application specific DSL&amp;#39;s for wiring the screens together&lt;/li&gt;
&lt;li&gt;Convention over Configuration applied to .NET -- Not just for the Ruby on Rails guys.&amp;nbsp; What tricks can we do inside .Net architectures to go faster?&lt;/li&gt;
&lt;li&gt;Software Design and Testability&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Logo-NDC-2009.jpg"&gt;&lt;img src="http://codebetter.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Logo-NDC-2009.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;#39;m not sure about the exact timing or topic yet, but I&amp;#39;m also planning on speaking at the Bergen .Net Users Group as well earlier that week (and doing some tourist-ey sightseeing).&lt;/p&gt;
&lt;p&gt;See you there!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=201436" width="1" height="1"&gt;</description></item></channel></rss>