<?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>More signs of FubuMVC getting real</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/09/more-signs-of-fubumvc-getting-real.aspx</link><pubDate>Tue, 09 Feb 2010 14:52:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:624127</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>1</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=624127</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/09/more-signs-of-fubumvc-getting-real.aspx#comments</comments><description>&lt;p&gt;Just launched last night:&amp;nbsp; &lt;a href="http://guides.fubumvc.com/"&gt;http://guides.fubumvc.com/.&lt;/a&gt;&amp;nbsp; The main page has been around for a couple weeks now at &lt;a href="http://fubumvc.com/"&gt;http://fubumvc.com/.&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#39;s not that much yet, but I think the existence of *any* documentation at this point is a good indication that we&amp;#39;re serious about making the FubuMVC reboot take off.&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re interested in getting involved, there&amp;#39;s a TODO list that Chad &amp;amp; I are trying to keep up with ideas for extending FubuMVC at &lt;a href="http://wiki.fubumvc.com/TODO"&gt;http://wiki.fubumvc.com/TODO&lt;/a&gt; and the developers list is at &lt;a href="http://groups.google.com/group/fubumvc-devel"&gt;http://groups.google.com/group/fubumvc-devel&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=624127" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx">FubuMVC</category></item><item><title>StructureMap 2.6 (and 2.5.4) is Released!</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/04/structuremap-2-6-and-2-5-4-is-released.aspx</link><pubDate>Thu, 04 Feb 2010 15:14:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:619980</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>20</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=619980</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/04/structuremap-2-6-and-2-5-4-is-released.aspx#comments</comments><description>&lt;p&gt;Time flies when you&amp;rsquo;re having fun.&amp;nbsp; It&amp;rsquo;s been almost a year since I&amp;rsquo;ve made an official StructureMap release, so I guess it&amp;rsquo;s about time.&amp;nbsp; This morning I uploaded &lt;a href="https://sourceforge.net/projects/structuremap/files/"&gt;the binaries for the 2.6 release&lt;/a&gt;.&amp;nbsp; This release just adds some bug fixes and a couple minor additions to the 2.5.4 release that I made in December but didn&amp;rsquo;t really publicize.&amp;nbsp; The release notes below are long, but that&amp;rsquo;s because they represent almost a year&amp;rsquo;s worth of development.&amp;nbsp; As I said yesterday, StructureMap is most likely moving to GitHub with the documentation going as well.&amp;nbsp; After a massive effort to write documentation early last year, huge chunks of it is already obsolete and there&amp;rsquo;s been a lot of addition since.&amp;nbsp; I&amp;rsquo;m hoping that the move to the Wiki will make it easier to keep the docs up.&amp;nbsp; In the meantime, I&amp;rsquo;ll try to blog a bit about the newer pieces starting tomorrow.&lt;/p&gt;
&lt;p&gt;A tiny bit of history.&amp;nbsp; This is the 11th StructureMap release since it debuted way back in June of 2004.&amp;nbsp; Almost nothing is the same.&amp;nbsp; We use it differently, the expectations are different, and very, very little of the original code survives today.&amp;nbsp; At QCon San Francisco in 2008 I talked about &lt;a href="http://www.infoq.com/presentations/Lessons-Learned-Jeremy-Miller"&gt;what I&amp;rsquo;d learned&lt;/a&gt; from evolving this codebase over so many years and changes.&lt;/p&gt;
&lt;p&gt;This release includes a lot of patches from the community, and I&amp;rsquo;d like to thank all of you for that &amp;ndash; especially Frank Quednau and Andreas Ohlund for taking on some nastier things.&amp;nbsp; Josh and Kevin Miller do yeoman duty answering StackOverflow questions (so I don&amp;rsquo;t have to).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;What&amp;rsquo;s Changed?&lt;/b&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;New terse, &amp;ldquo;jQuery-esque&amp;rdquo; syntax for the Registry DSL.&amp;nbsp; Let&amp;rsquo;s just write off &amp;ldquo;ForRequestedType&amp;lt;IFoo&amp;gt;().TheDefault.Is.OfConcreteType&amp;lt;Foo&amp;gt;()&amp;rdquo; as a well meant experiment, shall we?&amp;nbsp; It&amp;rsquo;s still in the codebase, but it&amp;rsquo;s marked as [Obsolete].&amp;nbsp; Nobody liked it and I thought it was annoying in real life usage.&amp;nbsp; Now, just do:&amp;nbsp; For&amp;lt;IFoo&amp;gt;().Use&amp;lt;Foo&amp;gt;();&amp;nbsp; My whole goal was to reduce friction.&amp;nbsp; Needs a big blog post&lt;/li&gt;
&lt;li&gt;Changed the Registry DSL to make inline dependency configuration be more consistent.&amp;nbsp; Definitely a blog post.&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;CreateProfile&amp;rdquo; syntax has gotten a lot of complaints for being inconsistent with the rest of the Registry DSL.&amp;nbsp; I basically rewrote it to now be consistent with the &amp;ldquo;For&amp;lt;&amp;gt;().Use()&amp;rdquo; syntax in the main Registry DSL.&amp;nbsp; Blog post coming soon&amp;hellip;.&lt;/li&gt;
&lt;li&gt;Nested Container feature for short lived transactional requests.&amp;nbsp; I built this for Dovetail usage, but I think it&amp;rsquo;s my preferred way to manage object scoping in certain circumstances.&amp;nbsp; I mentioned it just a little bit in my &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2010/01/06/how-dovetail-uses-structuremap-with-nhibernate.aspx"&gt;NHibernate w/ StructureMap&lt;/a&gt; post a couple weeks back.&amp;nbsp; Blog post coming soon&amp;hellip;&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;Model&amp;rdquo; feature was completely redone.&amp;nbsp; There&amp;rsquo;s a lot more power, and you can use it to pull services out of the Container and completely remove services from the Container as well.&amp;nbsp; Sigh.&amp;nbsp; Needs a blog post.&lt;/li&gt;
&lt;li&gt;Convention based type registration got a lot of work.&amp;nbsp; People are pushing this feature very hard and it had to grow.&amp;nbsp; You can now use the Registry DSL to write conventions.&amp;nbsp; This was improved farther in the latest code drop.&amp;nbsp; Yeah, blog post coming&amp;hellip;&lt;/li&gt;
&lt;li&gt;Better support for registering services by Type objects for cases when you don&amp;rsquo;t necessarily know the Type upfront.&amp;nbsp; Big request from several framework authors like &lt;a href="http://www.codeplex.com/caliburn"&gt;Caliburn&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A helluva lot of new features to make working with open generic types easier.&amp;nbsp; Jimmy Bogard &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/12/17/advanced-structuremap-connecting-implementations-to-open-generic-types.aspx"&gt;blogged about some of it here&lt;/a&gt;.&amp;nbsp; I&amp;rsquo;d like to show how StructureMap&amp;rsquo;s new features would make writing something like Davy Brion&amp;rsquo;s &lt;a href="http://davybrion.com/blog/category/agatha/"&gt;Agatha framework&lt;/a&gt; a snap.&amp;nbsp; I use this stuff extensively inside of StoryTeller.&lt;/li&gt;
&lt;li&gt;Added the lazy Func&amp;lt;T&amp;gt; feature from Autofac.&amp;nbsp; A really great (and cheap) way to support lazily initialized components.&amp;nbsp; Blog post coming.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Completely ditched all Reflection.Emit code&lt;/b&gt;.&amp;nbsp; StructureMap now strictly uses dynamically constructed Expression&amp;rsquo;s that are pre-compiled into cached Func&amp;rsquo;s.&amp;nbsp; I don&amp;rsquo;t know if that really makes much difference to users, but it makes StructureMap much, much easier to extend.&amp;nbsp; The container does spin up faster with this mechanism.&amp;nbsp; Makes &lt;b&gt;me&lt;/b&gt; happy.&lt;/li&gt;
&lt;li&gt;Supports IList&amp;lt;T&amp;gt; and List&amp;lt;T&amp;gt; arguments.&amp;nbsp; It works just like Arrays.&amp;nbsp; That&amp;rsquo;s been a while coming.&lt;/li&gt;
&lt;li&gt;You can set the lifecycle from &amp;lt;AddInstance&amp;gt; if you happen to still use Xml configuration.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;The &amp;ldquo;Lifecycle&amp;rdquo; code was completely reworked to eliminate shared code&lt;/li&gt;
&lt;li&gt;Container.Dispose() was introduced.&amp;nbsp; I&amp;rsquo;ve put a lot of effort into making StructureMap clean up after itself.&amp;nbsp; Definitely a blog post coming.&lt;/li&gt;
&lt;li&gt;ObjectFactory.Container.&amp;nbsp; Slowly, but surely, I&amp;rsquo;d like to wean people away from using ObjectFactory too much in favor of scoped Container objects.&amp;nbsp; I will NOT be further extending the ObjectFactory static methods to synchronize it with IContainer.&amp;nbsp; Instead, I&amp;rsquo;m just exposing the ObjectFactory.Container property.&lt;/li&gt;
&lt;li&gt;New abilities for IContext like BuildUp() (thanks to Kyle Malloy), getting all instances, and TryGetInstance&lt;/li&gt;
&lt;li&gt;TryGetInstance() from Josh&lt;/li&gt;
&lt;li&gt;Killed StructureMapConfiguration.&amp;nbsp; Good riddance.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Forwarding&amp;rdquo; requests for IFoo to whatever IBar is&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=619980" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/StructureMap/default.aspx">StructureMap</category></item><item><title>Getting StructureMap off SourceForge, Thoughts?</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/03/getting-structuremap-off-sourceforge-thoughts.aspx</link><pubDate>Wed, 03 Feb 2010 22:29:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:618163</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>22</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=618163</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/03/getting-structuremap-off-sourceforge-thoughts.aspx#comments</comments><description>&lt;p&gt;The original discussion for this topic is here:&amp;nbsp; http://groups.google.com/group/structuremap-users/browse_thread/thread/6d579f4e9b508c66&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;All,&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve never liked SourceForge and it&amp;#39;s a PITA for me to use even though it&amp;#39;s gotten better over the years. &amp;nbsp;I&amp;#39;d like &lt;br /&gt; to move StructureMap off SourceForge and more importantly, get a real &lt;br /&gt; Wiki site up so that we have at least a fighting chance of keeping the &lt;br /&gt; documentation up to date. &amp;nbsp;On the other hand, I get a significant &lt;br /&gt; number of patches from you guys (thanks for that) and I&amp;#39;d also like a &lt;br /&gt; better way of handling those submissions -- and making it easier for &lt;br /&gt; *you* to get involved.&lt;/p&gt;
&lt;p&gt;Right now, Josh and I are thinking about moving StructureMap to GitHub &lt;br /&gt; (you knew that was coming) and trying to use the Wiki support on &lt;br /&gt; Github for now. &amp;nbsp;Granted, Git is weird as hell for those of us used to &lt;br /&gt; SVN, but GitHub has some huge advantages for OSS community &lt;br /&gt; development. &amp;nbsp;I&amp;#39;d *love* to start managing StructureMap patches &lt;br /&gt; through GitHub &amp;quot;pull&amp;quot; requests (or whatever the correct lingo is).&lt;/p&gt;
&lt;p&gt;Any thoughts? &amp;nbsp;Volunteers? ;)&lt;/p&gt;
&lt;p&gt;Jeremy &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=618163" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/StructureMap/default.aspx">StructureMap</category></item><item><title>FubuMVC Learns to Speak Spark</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/02/fubumvc-learns-to-speak-spark.aspx</link><pubDate>Tue, 02 Feb 2010 17:59:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:617884</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>3</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=617884</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/02/02/fubumvc-learns-to-speak-spark.aspx#comments</comments><description>&lt;p&gt;From Robert the Grey, &lt;a href="http://blog.cozwecan.com/2010/02/spark-learns-to-speak-fubu.html"&gt;FubuMVC learns to speak Spark&lt;/a&gt;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I&amp;#39;ve done the nearly solo OSS thing a couple times to mixed results.&amp;nbsp; I&amp;#39;m painfully aware that good OSS projects have a deeper community of contributors than just one guy, and that&amp;#39;s why I&amp;#39;m so thrilled to see this addition come into the nascent FubuMVC reboot from outside the Dovetail office.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=617884" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx">FubuMVC</category></item><item><title>Dovetail is Hiring</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/29/dovetail-is-hiring.aspx</link><pubDate>Fri, 29 Jan 2010 21:17:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:611946</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>2</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=611946</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/29/dovetail-is-hiring.aspx#comments</comments><description>&lt;p&gt;This is a different project than the one we hired for last time.&amp;nbsp; If you&amp;#39;ve spoken to us before, please consider this position separately.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We&amp;#39;re expanding the development team on our line of existing
products. You&amp;#39;ll be working on a small team that develops applications
for large businesses using some of the latest technology. You will be
involved in all aspects of solution development, including analysis,
design, development, testing, documentation, and support.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re
looking for a software developer with demonstrable C# (preferably .NET
2.0 or later) and HTML/CSS experience (ASP.NET MVC is a plus). Any
experience with test-driven development or automated unit testing in
general is a huge plus. Also, participation in the community
(attendance of events, avid blog reader + commenter, or maybe you even
have a blog yourself) will put you firmly in the running for this
position. We&amp;rsquo;re looking for people that believe learning and continuous
improvement are primary responsibilities of a software developer. We&amp;rsquo;re
hiring motivated people for a terrific opportunity with a team of
recognized .NET and agile community leaders.&lt;/p&gt;
&lt;p&gt;Our practices and technologies include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test-driven development &lt;/li&gt;
&lt;li&gt;Continuous integration &lt;/li&gt;
&lt;li&gt;Behavior-driven design &lt;/li&gt;
&lt;li&gt;Domain-driven design &lt;/li&gt;
&lt;li&gt;HTML, CSS, Javascript (jQuery) &lt;/li&gt;
&lt;li&gt;ASP .NET MVC &lt;/li&gt;
&lt;li&gt;C# 3.0, .NET 3.5, Visual Studio 2008 &lt;/li&gt;
&lt;li&gt;SQL 2008 &lt;/li&gt;
&lt;li&gt;Oracle &lt;/li&gt;
&lt;li&gt;NHibernate 2.x &lt;/li&gt;
&lt;li&gt;StructureMap&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Email us and tell us why you&amp;rsquo;d make a great addition to our team: &lt;a href="mailto:tech-jobs@dovetailsoftware.com"&gt;tech-jobs@dovetailsoftware.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a full-time, on-site position in our Austin, TX office. Please DO NOT contact us for outsourcing or tele-commuting.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=611946" width="1" height="1"&gt;</description></item><item><title>Shrink your Views with FubuMVC Html Conventions</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/29/shrink-your-views-with-fubumvc-html-conventions.aspx</link><pubDate>Fri, 29 Jan 2010 17:00:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:611847</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>8</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=611847</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/29/shrink-your-views-with-fubumvc-html-conventions.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Yesterday I was able to &amp;ldquo;push&amp;rdquo; into Github the work I&amp;rsquo;ve been doing for convention based Html generation in FubuMVC.&amp;nbsp; What the hell is &amp;ldquo;convention based Html generation?&amp;rdquo; you ask?&amp;nbsp; It&amp;rsquo;s simple in concept.&amp;nbsp; Your team has policies, formal or informal, for how you build Html elements for the fields in a ViewModel.&amp;nbsp; If your familiar with MvcContrib&amp;rsquo;s &lt;a href="http://www.lostechies.com/blogs/hex/archive/2009/06/09/opinionated-input-builders-for-asp-net-mvc-using-partials-part-i.aspx"&gt;Opinionated Input Builders&lt;/a&gt; or MVC2&amp;rsquo;s Templates feature (very well described by &lt;a href="http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html"&gt;Brad Wilson here&lt;/a&gt;), we&amp;rsquo;re doing the same thing &lt;i&gt;conceptually&lt;/i&gt; but with much different mechanics.&amp;nbsp; Right now, I&amp;rsquo;m focused on the very basic building block methods that appear on FubuMVC view&amp;rsquo;s (remember that we basically force all views in FubuMVC to be strongly typed with a single ViewModel):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;InputFor( expression ) &amp;ndash; write an Html element to edit a single property on the ViewModel.&amp;nbsp; Instead of calling TextboxFor(x =&amp;gt; x.Something) or DropdownListFor(x =&amp;gt; x.Other) we can just say InputFor(x =&amp;gt; x.Some.Property.On.The.ViewModel) and let the conventions figure out what to do from there.&amp;nbsp; If we need to change the model property to something else, or change our conventions about how elements should be constructed, no big deal.&lt;/li&gt;
&lt;li&gt;DisplayFor( expression ) &amp;ndash; write an Html element to display the value of a single property value on the ViewModel.&amp;nbsp; String fields are just displayed.&amp;nbsp; Entity fields may be displayed as a link to more information on that link.&amp;nbsp; Date fields are shown in short date format, etc.&lt;/li&gt;
&lt;li&gt;LabelFor( expression ) &amp;ndash; write an Html &amp;ldquo;label&amp;rdquo; element for the field.&amp;nbsp; Out of the box, FubuMVC will just put in the field name, but that&amp;rsquo;s not all that useful.&amp;nbsp; In our Dovetail project we have this tied into our localization subsystem to pluck out a localized header text for the desired property.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m dubious that the form auto-generation stuff that MVC2 does has much real world value, but it would certainly be possible to build on top of what we already have.&amp;nbsp; In a follow up post I&amp;#39;ll show more of the DSL-ey approach for creating simple forms that uses InputFor/DisplayFor/LabelFor as building blocks.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Example&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;In our system we have a small Entity class named Address (all systems of any complexity have an &amp;ldquo;Address&amp;rdquo; class, but they&amp;rsquo;re all different) with a property for the first line of the address called Address1:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;Required&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;MaximumStringLength&lt;/span&gt;(250)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Address1 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Leaving the appropriateness of the approach aside (it&amp;rsquo;s working very well), we use attributes for our simple validation rules (and also use those to generate &amp;ldquo;not null&amp;rdquo; / string length types of rules in our database).&amp;nbsp; On the client side, we use &lt;a href="http://docs.jquery.com/Plugins/Validation"&gt;jQuery Validation&lt;/a&gt; to do input validation in the browser.&amp;nbsp; jQuery Validation is very simple to use (as long as you color within the lines).&amp;nbsp; All I need to do is add classes and some attributes to the &amp;lt;input&amp;gt; and &amp;lt;select&amp;gt; elements to declaratively apply validation rules.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In usage, we could build the input Html element for a field by just calling InputFor() like this:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;dd&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background:#ffee62;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.InputFor(m =&amp;gt; m.Site.PrimaryAddress.Address1).Id(&lt;span style="color:#a31515;"&gt;&amp;quot;site-address1&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;dd&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In our Dovetail system the above call generates this Html:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;input&lt;/span&gt; &lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;site-address1&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;required&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;SitePrimaryAddressAddress1&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Address 1&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;maxlength&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;250&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Did you see what happened there?&amp;nbsp; When we create an input element for the Address.Address1, the conventions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Built a textbox element.&amp;nbsp; If the property was a boolean, the conventions would build a checkbox instead.&amp;nbsp; Likewise, if the property is a DateTime or DateTime? field the conventions would build a date picker.&lt;/li&gt;
&lt;li&gt;Set a &amp;ldquo;name&amp;rdquo; attribute&amp;rdquo; that matches our naming convention so that model binding works smoothly from client to server and in automated testing scenarios.&amp;nbsp; In our case we just take the &amp;ldquo;path&amp;rdquo; to a property from the ViewModel and tear out the &amp;ldquo;.&amp;rdquo; characters&lt;/li&gt;
&lt;li&gt;Adds the &amp;quot;label&amp;rdquo; attribute with the localized header name for this field.&amp;nbsp; This is used in conjunction with the jQuery validation to present a clean, localized validation summary on the screen&lt;/li&gt;
&lt;li&gt;Recognizes the presence of the [MaximumStringLength] attribute and sets the &amp;ldquo;maxlength&amp;rdquo; attribute&lt;/li&gt;
&lt;li&gt;Puts the property value into the &amp;ldquo;value&amp;rdquo; attribute.&amp;nbsp; The example I used happens to come from a &amp;ldquo;New&amp;rdquo; screen, so the value is blank&lt;/li&gt;
&lt;li&gt;Recognizes the presence of the [Required] attribute and adds the &amp;ldquo;required&amp;rdquo; class to the element&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By the way, did you see how I overrode the &amp;ldquo;id&amp;rdquo; property of that textbox?&amp;nbsp; I&amp;rsquo;ll talk more about that at the bottom, but that represents a huge advantage that FubuMVC&amp;rsquo;s model has over both MvcContrib and MVC2.&amp;nbsp; &lt;b&gt;You can happily modify or enhance the convention-generated Html input on a case by case basis&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Can I make my own Conventions?&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;One of the overarching principles of FubuMVC is to push the usage of Convention over Configuration as far as it can go while still allowing FubuMVC adopters to create and add their own conventions.&amp;nbsp; The Html conventions are no different.&amp;nbsp; When you register / configure conventions for the Html you can register either &amp;ldquo;Builders&amp;rdquo; that know how to generate the HtmlTag (I&amp;rsquo;ll explain HtmlTags later) for a certain class of properties:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;delegate&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TagBuilder&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ElementRequest&lt;/span&gt; request);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IElementBuilder&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;TagBuilder&lt;/span&gt; CreateInitial(&lt;span style="color:#2b91af;"&gt;AccessorDef&lt;/span&gt; accessorDef);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;or &amp;ldquo;Modifiers&amp;rdquo; that enrich HtmlTag&amp;rsquo;s:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;delegate&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TagModifier&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ElementRequest&lt;/span&gt; request, &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; tag);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IElementModifier&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;TagModifier&lt;/span&gt; CreateModifier(&lt;span style="color:#2b91af;"&gt;AccessorDef&lt;/span&gt; accessorDef);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;These ElementBuilder&amp;rsquo;s and ElementModifier&amp;rsquo;s can either be classes that you build yourself and &amp;ldquo;plug&amp;rdquo; in, or you can use the Html convention DSL shown below to create common, simple types of policies (think, if this attribute exists, add this class).&amp;nbsp; A custom ElementBuilder might look like this:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// This builder is only for creating the display tag&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// for a date time field on one of our &amp;quot;activity log&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// models&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;LogDateDisplay&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;ElementBuilder&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Does this builder apply to a property?&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; matches(&lt;span style="color:#2b91af;"&gt;AccessorDef&lt;/span&gt; def)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;return&lt;/span&gt; def.ModelType.Closes(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;LogViewModel&lt;/span&gt;&amp;lt;&amp;gt;)) &amp;amp;&amp;amp; def.Accessor.PropertyType.IsDateTime();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Renders a date in long time format and also sticks the header&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// text into the title attribute&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; Build(&lt;span style="color:#2b91af;"&gt;ElementRequest&lt;/span&gt; request)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;string&lt;/span&gt; title = &lt;span style="color:#2b91af;"&gt;LocalizationManager&lt;/span&gt;.GetHeader(request.Accessor.InnerProperty);&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;span&amp;quot;&lt;/span&gt;).Text(request.ToDisplay(&lt;span style="color:#a31515;"&gt;&amp;quot;{0:F}&amp;quot;&lt;/span&gt;)).Title(title);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Alrighty, let&amp;rsquo;s move on to registering our conventions.&amp;nbsp; From the top, I create a class to hold my project&amp;rsquo;s Html conventions like so:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// HtmlConventionRegistry is the base class that provides the DSL&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// This is an example of &amp;quot;Object Scoping&amp;quot; from Fowler speak like&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// StructureMap&amp;#39;s Registry and Fluent NHibernate&amp;#39;s ClassMap&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;DovetailHtmlConventions&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;HtmlConventionRegistry&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; DovetailHtmlConventions()&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; validationAttributes();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Profile(&lt;span style="color:#a31515;"&gt;&amp;quot;edit&amp;quot;&lt;/span&gt;, x =&amp;gt; x.Editors.Builder&amp;lt;&lt;span style="color:#2b91af;"&gt;EditInPlaceBuilder&lt;/span&gt;&amp;gt;());&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; editors();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Labels.Builder&amp;lt;&lt;span style="color:#2b91af;"&gt;LabelBuilder&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Displays.Builder&amp;lt;&lt;span style="color:#2b91af;"&gt;LogDateDisplay&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Displays.Builder&amp;lt;&lt;span style="color:#2b91af;"&gt;DisplayBuilder&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; editors()&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.Builder&amp;lt;&lt;span style="color:#2b91af;"&gt;ValueObjectDropdownBuilder&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.IfPropertyIs&amp;lt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;().BuildBy(request =&amp;gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;CheckboxTag&lt;/span&gt;(request.Value&amp;lt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;()).Style(&lt;span style="color:#a31515;"&gt;&amp;quot;width&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;auto !important&amp;quot;&lt;/span&gt;).Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;, request.ElementId));&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.Always.Modify((request, tag) =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; tag.Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;label&amp;quot;&lt;/span&gt;, request.Header());&lt;/p&gt;
&lt;p style="margin:0px;"&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; tag.Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;, request.ElementId);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:green;"&gt;// Ugly hack because of the hacky Edit in Place jQuery plugin we use, but&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:green;"&gt;// I&amp;#39;m gonna kill it some day&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.IfPropertyTypeIs(t =&amp;gt; t.IsDateTime()).Modify(x =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (!x.HasMetaData(&lt;span style="color:#2b91af;"&gt;EditInPlaceBuilder&lt;/span&gt;.EDITABLE_ATTRIBUTE_NAME))&lt;/p&gt;
&lt;p style="margin:0px;"&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; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; x.AddClass(&lt;span style="color:#a31515;"&gt;&amp;quot;DatePicker&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&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; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Setting up rules for tagging elements with jQuery validation&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// metadata&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// I think that a lot of this gets added into the core Fubu as a&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// &amp;quot;jQueryValidationPack&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; numbers()&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.IfPropertyIs&amp;lt;&lt;span style="color:#2b91af;"&gt;Int32&lt;/span&gt;&amp;gt;().Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;max&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Int32&lt;/span&gt;.MaxValue);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.IfPropertyIs&amp;lt;&lt;span style="color:#2b91af;"&gt;Int16&lt;/span&gt;&amp;gt;().Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;max&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Int16&lt;/span&gt;.MaxValue);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.IfPropertyIs&amp;lt;&lt;span style="color:#2b91af;"&gt;Int64&lt;/span&gt;&amp;gt;().Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;max&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Int64&lt;/span&gt;.MaxValue);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.IfPropertyTypeIs(t =&amp;gt; t.IsIntegerBased()).AddClass(&lt;span style="color:#a31515;"&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.IfPropertyTypeIs(t =&amp;gt; t.IsFloatingPoint()).AddClass(&lt;span style="color:#a31515;"&gt;&amp;quot;number&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Declare policies for using validation attributes&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; validationAttributes()&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.AddClassForAttribute&amp;lt;&lt;span style="color:#2b91af;"&gt;RequiredAttribute&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.ModifyForAttribute&amp;lt;&lt;span style="color:#2b91af;"&gt;MaximumStringLengthAttribute&lt;/span&gt;&amp;gt;((tag, att) =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (att.Length &amp;lt; &lt;span style="color:#2b91af;"&gt;Entity&lt;/span&gt;.UnboundedStringLength)&lt;/p&gt;
&lt;p style="margin:0px;"&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; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; tag.Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;maxlength&amp;quot;&lt;/span&gt;, att.Length);&lt;/p&gt;
&lt;p style="margin:0px;"&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; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.ModifyForAttribute&amp;lt;&lt;span style="color:#2b91af;"&gt;GreaterOrEqualToZeroAttribute&lt;/span&gt;&amp;gt;(tag =&amp;gt; tag.Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;min&amp;quot;&lt;/span&gt;, 0));&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.ModifyForAttribute&amp;lt;&lt;span style="color:#2b91af;"&gt;GreaterThanZeroAttribute&lt;/span&gt;&amp;gt;(tag =&amp;gt; tag.Attr(&lt;span style="color:#a31515;"&gt;&amp;quot;min&amp;quot;&lt;/span&gt;, 1));&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;HtmlTags&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;The basis for FubuMVC&amp;rsquo;s Html conventions, and the big differentiating feature from the MVC2 and MvcContrib approach, is the usage of the &amp;ldquo;HtmlTags&amp;rdquo; library as a &lt;a href="http://martinfowler.com/dslwip/SemanticModel.html"&gt;semantic model&lt;/a&gt;.&amp;nbsp; All the Html generation in FubuMVC works by building up HtmlTag objects that represent an Html element graph (HtmlTag&amp;rsquo;s can have children).&amp;nbsp; Think of the old &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.tagbuilder_members.aspx"&gt;TagBuilder class&lt;/a&gt; on steroids.&amp;nbsp; A picture&amp;rsquo;s worth a thousand words, so let&amp;rsquo;s see some samples of HtmlTag in action:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&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 style="color:green;"&gt;// Setting the inner text and adding a class&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; tag = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;div&amp;quot;&lt;/span&gt;).Text(&lt;span style="color:#a31515;"&gt;&amp;quot;my text&amp;quot;&lt;/span&gt;).AddClass(&lt;span style="color:#a31515;"&gt;&amp;quot;collapsible&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&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 style="color:green;"&gt;// adding &amp;quot;MetaData&amp;quot; for the jQuery MetaData plugin&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; tag = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;div&amp;quot;&lt;/span&gt;).Text(&lt;span style="color:#a31515;"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tag.MetaData(&lt;span style="color:#a31515;"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;, 1);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tag.MetaData(&lt;span style="color:#a31515;"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;b-value&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; render_multiple_levels_of_nesting_2()&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; tag = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;html&amp;quot;&lt;/span&gt;).Modify(x =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; x.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;head&amp;quot;&lt;/span&gt;, head =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&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; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; head.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;).Text(&lt;span style="color:#a31515;"&gt;&amp;quot;The title&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&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; head.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;style&amp;quot;&lt;/span&gt;).Text(&lt;span style="color:#a31515;"&gt;&amp;quot;the style&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&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; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&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; x.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;body/div&amp;quot;&lt;/span&gt;).Text(&lt;span style="color:#a31515;"&gt;&amp;quot;inner text of div&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tag.ToCompacted().ShouldEqual(&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;The title&amp;lt;/title&amp;gt;&amp;lt;style&amp;gt;the style&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;div&amp;gt;inner text of div&amp;lt;/div&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The HtmlTag model has been hugely advantageous because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It greatly simplifies Html construction.&amp;nbsp; No ugly string bashing, class and attribute merging is handled internally by HtmlTag itself, and we&amp;rsquo;ve got plenty of convenience shortcuts.&amp;nbsp; Compare this model to using user controls with tag soup or brute force string manipulation&lt;/li&gt;
&lt;li&gt;Allows us to create an incremental model of &amp;ldquo;policies&amp;rdquo; to add classes and attributes to elements rather than having to make one big blob of code to create the Html (something that plagues both the MvcContrib and MVC2 designs)&lt;/li&gt;
&lt;li&gt;The InputFor(), DisplayFor(), and LabelFor() methods all return the HtmlTag object created by the convention, and HtmlTag itself has fluent builders so that you can override or extend the Html created by the conventions on a case by case basis.&amp;nbsp; We&amp;rsquo;ve gotten some great feedback and help with this feature from the MvcContrib guys, and this is their main complaint with using User Controls.&lt;/li&gt;
&lt;li&gt;The conventional Html generation is pretty testable in basic xUnit tests without ever having to mess with WatiN or Selenium.&amp;nbsp; That&amp;rsquo;s a huge plus in my book&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;HtmlTags is a separate library within FubuMVC that can be used independently (I use it in StoryTeller now). &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Select Box Example&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ve had this feature, and even the technical direction, in mind since last summer.&amp;nbsp; I finally got to build it out for Dovetail usage because we needed to change the way we do configurable lists in our system.&amp;nbsp; We keep list data in a database table where it&amp;rsquo;s easily editable and extensible (even to the point of adding cascading relationships after the fact for customizations).&amp;nbsp; We need to validate certain fields against that list data, so we mark those fields like this:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// There is no logic associated with Origin&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// other than externalized rules, so having it&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// be a string does no harm&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;Required&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;ValueOf&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ListNames&lt;/span&gt;.Origin)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Origin { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Anytime a property is decorated with the [ValueOf] attribute we know that we need to build a dropdown list to edit that field.&amp;nbsp; All the information that we absolutely need to know to construct that dropdown is available on the property itself, so it made perfect sense to move to convention based Html construction instead of all the repetitive &amp;ldquo;put list data on ViewModel in Controller, transmit to View, fill options in View code&amp;rdquo; work we were doing before.&amp;nbsp; We cache the list data in a static class called ValueObjectRegistry that can give us list data.&amp;nbsp; Using ValueObjectRegistry and the Html Conventions gave us this:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Builds a &amp;lt;select&amp;gt; tag and fills in the list values &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// for any property in our system that is &amp;quot;marked&amp;quot; as being&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// a list field&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;ValueObjectDropdownBuilder&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;ElementBuilder&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; matches(&lt;span style="color:#2b91af;"&gt;AccessorDef&lt;/span&gt; def)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;return&lt;/span&gt; def.Accessor.HasAttribute&amp;lt;&lt;span style="color:#2b91af;"&gt;ValueOfAttribute&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; Build(&lt;span style="color:#2b91af;"&gt;ElementRequest&lt;/span&gt; request)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;string&lt;/span&gt; defaultValue = request.Value&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;if&lt;/span&gt; (defaultValue.IsEmpty())&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; request.ForListName(name =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&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; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:#2b91af;"&gt;ValueObject&lt;/span&gt; @default = &lt;span style="color:#2b91af;"&gt;ValueObjectRegistry&lt;/span&gt;.FindDefault(name);&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (@default != &lt;span style="color:blue;"&gt;null&lt;/span&gt;) defaultValue = @default.Key;&lt;/p&gt;
&lt;p style="margin:0px;"&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; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SelectTag&lt;/span&gt;(tag =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; request.EachValueObject(vo =&amp;gt; tag.Option(vo.LocalizedText(), vo.Key));&lt;/p&gt;
&lt;p style="margin:0px;"&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; tag.SelectByValue(defaultValue);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; Build(&lt;span style="color:blue;"&gt;string&lt;/span&gt; listName)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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 style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SelectTag&lt;/span&gt;(tag =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:#2b91af;"&gt;ValueObjectRegistry&lt;/span&gt;.GetAllActive(listName).Each(x =&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&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; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; tag.Option(x.LocalizedText(), x.Key);&lt;/p&gt;
&lt;p style="margin:0px;"&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; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;var&lt;/span&gt; defaultVO = &lt;span style="color:#2b91af;"&gt;ValueObjectRegistry&lt;/span&gt;.FindDefault(listName);&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (defaultVO != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin:0px;"&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; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; tag.SelectByValue(defaultVO.Key);&lt;/p&gt;
&lt;p style="margin:0px;"&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; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now that we have ValueObjectDropdownBuilder hooked into our Html conventions, all I need to do on the view is just say:&amp;nbsp; &amp;ldquo;InputFor(x =&amp;gt; x.Case.Origin)&amp;rdquo; and let the conventions handle everything.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Any questions?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=611847" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx">FubuMVC</category></item><item><title>Url Resolution in FubuMVC</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/24/url-resolution-in-fubumvc.aspx</link><pubDate>Mon, 25 Jan 2010 04:34:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:605577</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>4</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=605577</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/24/url-resolution-in-fubumvc.aspx#comments</comments><description>&lt;p&gt;Continuing the thread from my earlier update on the &amp;ldquo;&lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2009/12/15/an-update-on-the-fubumvc-reboot.aspx"&gt;Fubu Reboot&lt;/a&gt;.&amp;rdquo;&amp;nbsp; In an MVC web application (I think this really could apply to WebForms as well, but not to the same extent) you frequently need to resolve the Url that points to a specific subject.&amp;nbsp; In our application at Dovetail, we have the route pattern:&amp;nbsp; &amp;ldquo;sites/edit/{Id}&amp;rdquo; for the page that edits a &amp;ldquo;Site&amp;rdquo; object.&amp;nbsp; When we place links in the views for a given &amp;ldquo;Site&amp;rdquo; object, we need to replace &amp;ldquo;{Id}&amp;rdquo; in the route with the value of the Site.Id property.&amp;nbsp; In another circumstance, we have the routing pattern &amp;ldquo;query/for/{QueryName}/{QueryParam1}&amp;rdquo; for a controller action that takes in this object as its single argument:&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// The [RouteInput] attributes are *a* way to direct Fubu to &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// make these properties by automatically scanned as part of the &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// route pattern.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// This should only be necessary in exception cases&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// My hope is that conventions take you 90% of the way home&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;QueryForRequest&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;RouteInput&lt;/span&gt;]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; QueryName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;RouteInput&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; QueryParam1 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;At many, many times in our application we need to determine the Url string that points to a particular subject or occasionally to a controller action.&amp;nbsp; At the same time, it would be very, very nice to keep the individual controllers and views ignorant of exactly what those Url patterns happen to be in order to make them easier to change.&amp;nbsp; In FubuMVC, that&amp;rsquo;s all done with the IUrlRegistry interface that is automatically placed into your IoC container:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="border-bottom:black thin solid;border-left:black thin solid;font-family:courier new;background:white;color:black;font-size:10pt;border-top:black thin solid;border-right:black thin solid;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// This service is injected into your IoC tool of choice as a singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// to give you access to url&amp;#39;s in a type safe way&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Please note that this implementation in no way, shape, or form&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// locks you into a rigid url structure&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IUrlRegistry&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlFor(&lt;span style="color:blue;"&gt;object&lt;/span&gt; model);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlFor(&lt;span style="color:blue;"&gt;object&lt;/span&gt; model, &lt;span style="color:blue;"&gt;string&lt;/span&gt; category);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlFor&amp;lt;TController&amp;gt;(&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;TController&amp;gt;&amp;gt; expression);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlForNew&amp;lt;T&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlForNew(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; entityType);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Not sure these two methods won&amp;#39;t get axed.&amp;nbsp; They could just be extension methods in Dovetail code&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlForPropertyUpdate(&lt;span style="color:blue;"&gt;object&lt;/span&gt; model);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlForPropertyUpdate(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; type);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UrlFor(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; handlerType, &lt;span style="color:#2b91af;"&gt;MethodInfo&lt;/span&gt; method);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the FubuMVC model, we&amp;rsquo;re basically assuming that controller actions (&lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/archive/2010/01/18/fubumvc-define-your-actions-your-way.aspx"&gt;Fubu actions don&amp;rsquo;t have to be on special Controller classes&lt;/a&gt;, btw) take in 0 or 1 objects as their single input.&amp;nbsp; Taking another step, if you make the input model types unique per controller action, FubuMVC can actually use that type to &amp;ldquo;know&amp;rdquo; what controller action receives that type.&amp;nbsp; Therefore, when I need the Url string that points to a particular Site object, I just pass in that Site object to the UrlRegistry.For(object) method.&amp;nbsp; In the more complex case of the QueryForRequest object above, I do the exact same thing &amp;ndash; even though QueryForRequest clearly points to a different Route.&amp;nbsp; For controller actions that don&amp;rsquo;t take in any input arguments (think HomeController.Index()), you can still use UrlRegistry.UrlFor&amp;lt;HomeController&amp;gt;(x =&amp;gt; x.Index()).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;For those of you familiar with ASP.Net MVC&amp;rsquo;s model, here&amp;rsquo;s some other facts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The lookup of a Url for a Controller Type / Method combination makes no, let me repeat that, no assumptions about the Url pattern.&amp;nbsp; SomethingController.Method1() does not imply that the Url is &amp;ldquo;something/method1.&amp;rdquo;&amp;nbsp; FubuMVC is literally hashing the exact Route pattern for each Controller action and looks up the exact Url at runtime.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;The call to UrlFor() is completely independent of whether or not the Route in question was registered as part of the main application or as part of an Area/Slice.&amp;nbsp; Unlike MVC2, when you&amp;rsquo;re determining the Url to a certain controller action or input object, you do not have to worry about where&amp;nbsp;&amp;nbsp; I think the MVC team thoroughly screwed up their Area support and I&amp;rsquo;d surely hope they scrap it for something better in MVC3.&amp;nbsp; If you&amp;rsquo;re using the MVC framework today, I&amp;rsquo;d strongly recommend you use the bits in MvcContrib instead of MVC2 for areas.&amp;nbsp;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;No magic strings of any kind.&amp;nbsp; Anywhere.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Lastly,&lt;/h4&gt;
&lt;p&gt;The Url resolution is static typed.&amp;nbsp; That&amp;rsquo;s valuable to help prevent coding mistakes and Intellisense is also nice.&amp;nbsp; Honestly, my favorite part is how much more traceable it makes the code rather than relying on strings.&amp;nbsp; One quick CTRL-B shortcut takes you the the controller action behind the Url.&amp;nbsp; In the case of finding the Url for an object, it&amp;rsquo;s one more bounce with CTRL-ALT-F7 (one of my favorite R# shortcuts).&amp;nbsp; In real usage, we have convenience methods on our view types to get at action urls, as well as consuming the IUrlRegistry in our FormFor() and ActionUrlFor() type HtmlHelpers.&lt;/p&gt;
&lt;p&gt;Now that we mostly rely on IUrlRegistry.For(object), IUrlRegistry is relatively easy to mock in most tests.&amp;nbsp; If your tests have to rely on an Expression in IUrlRegistry.UrlFor&amp;lt;T&amp;gt;(x =&amp;gt; Method()), I&amp;#39;d go for some sort of hand rolled stub.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ok, this may be vague, so please ask question.&amp;nbsp; Also, this stuff isn&amp;rsquo;t locked down, so we can actually change it to suit.&amp;nbsp; And I won&amp;rsquo;t even get all paternalistic on you telling you that &amp;ldquo;UrlFor() doesn&amp;rsquo;t really mean UrlFor()&amp;rdquo; if you don&amp;rsquo;t like the API.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=605577" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx">FubuMVC</category></item><item><title>A Train of Thought: January 2010 Edition</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/24/a-train-of-thought-january-2010-edition.aspx</link><pubDate>Sun, 24 Jan 2010 23:09:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:605551</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>14</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=605551</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/24/a-train-of-thought-january-2010-edition.aspx#comments</comments><description>&lt;p&gt;One of my New Year&amp;rsquo;s resolutions was to resuscitate my blog.&amp;nbsp; It&amp;rsquo;s very obvious that the &amp;ldquo;conversation&amp;rdquo; has moved onto Twitter in the last couple years and my blogging output among many others has fallen off dramatically.&amp;nbsp; Instead of pushing little throwaway blurbs to Twitter and forgetting all about it, I thought I&amp;rsquo;d try the old way.&amp;nbsp; So here&amp;rsquo;s a bunch of throwaway blog comments&amp;hellip;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;On Entity Framework 4&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;I think EF4 looks worlds better than EF1 did.&amp;nbsp; There, &lt;a href="http://keithelder.net/blog/"&gt;are you happy Keith&lt;/a&gt;?&amp;nbsp; I still don&amp;rsquo;t like EF4 in comparison to you know what, but the remaining issues are much smaller than with the very seriously flawed v1 release.&lt;/p&gt;
&lt;p&gt;At this point, from the outside looking in, it looks like something that I could use if I ever got into a shop that couldn&amp;rsquo;t use OSS tooling or if it&amp;rsquo;s a project that doesn&amp;rsquo;t really need a rich domain model.&amp;nbsp; EF4 is still missing too many important features that my team depends on with NHibernate, but that gap has closed dramatically.&amp;nbsp; Specifically, if EF vNext supports &amp;ldquo;rich&amp;rdquo; POCO model (EF4&amp;rsquo;s &amp;ldquo;POCO&amp;rdquo; support only does anemic domain models and that is important to my team), closes the gap with Fluent NHibernate&amp;rsquo;s conventions and auto mapping support, and has the right plugin points for interceptors and NH&amp;rsquo;s &amp;ldquo;UserType&amp;rsquo;s,&amp;rdquo; then I have a real decision to make going forward in regards to persistence.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Context Matters&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Well, duh, Jeremy.&amp;nbsp; I&amp;rsquo;ve been in a lot of discussions over the last decade about the &amp;ldquo;best&amp;rdquo; way to develop software.&amp;nbsp; I think a lot of heated discussions could be headed off if we&amp;rsquo;d first lay down the context in which we arrived at our own opinions &amp;ndash; and probably stop using absolute terms in any case.&amp;nbsp; If you&amp;rsquo;re arguing with me that NHibernate is the wrong tool because you&amp;rsquo;re writing reporting applications, just say &amp;ldquo;I write reporting applications.&amp;rdquo;&amp;nbsp; And when I say &amp;ldquo;I think NHibernate is the best tool for persisting domain models,&amp;rdquo; I should probably talk about that specific context.&amp;nbsp; And definitely, when you say &amp;ldquo;Linq to Sql rocks!&amp;rdquo; you better follow that up with &amp;ldquo;for applications with simplistic domain models.&amp;rdquo; &lt;/p&gt;
&lt;p&gt;I apparently work in a magic fairy land where my development team is free to choose any tool that we deem best for us regardless of whether or not that tool is bundled into Visual Studio or not.&amp;nbsp; I also work in a very small team that&amp;rsquo;s perfectly co-located and mostly staffed with experienced developers so I can happily consider introducing new concepts.&amp;nbsp; Many of you labor in a world where your choices are are circumscribed by corporate policies or the infamous centralized architecture team.&amp;nbsp; The point is that what&amp;rsquo;s best for me may be radically different than it is for somebody working in a typical large corporate IT department that doesn&amp;rsquo;t allow any non-Microsoft tools.&amp;nbsp; It&amp;rsquo;s to the point where I want a new rule in place for any new debates - &amp;ldquo;are we talking about the best way to do things or the best way we can do things within your specific set of constraints.&amp;rdquo;&amp;nbsp; Both topics are interesting, but let&amp;rsquo;s get the ground rules out first.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;You obviously need to limit your technologies and approaches to your existing context, but don&amp;rsquo;t forget that can also change your context to better fit the way you want to work.&amp;nbsp; My friend &lt;a href="http://codebetter.com/blogs/rodpaddock"&gt;Rod Paddock&lt;/a&gt; wrote an article a couple months back called &lt;a href="http://codebetter.com/blogs/rodpaddock/archive/2009/11/28/can-a-fish-use-a-bicycle.aspx"&gt;Can a Fish Use a Bicycle?&lt;/a&gt; about how Agile techniques and philosophy are independent of tools and universally applicable.&amp;nbsp; Rod specifically mentions some technologies that are not normally associated with Agile development.&amp;nbsp; I&amp;rsquo;m not going to directly disagree with Rod, but let&amp;rsquo;s just say that I think Agile techniques work much better in some contexts than others.&amp;nbsp; Agile techniques work best when the lines of communication between team members are better, so co-locate the team whenever possible and tear down the cubicle walls.&amp;nbsp; TDD/BDD works best with technologies where it&amp;rsquo;s easier to isolate little bits of the code &amp;ndash; so choose those technologies when you can.&amp;nbsp; Incremental delivery works best when you&amp;rsquo;re using technologies where it&amp;rsquo;s efficient to make a series of small changes to the existing codebases.&amp;nbsp; If you can, change the way you work to better utilize the tools and techniques.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Oh, and even if you do work within certain constraints, I still think it&amp;rsquo;s a good thought experiment to consider how you would solve problems if you could use anything.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;My tool is better because it has feature XYZ and your tool doesn&amp;rsquo;t!&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Here&amp;rsquo;s an embarrassing moment from my career.&amp;nbsp; Like many, many VB6 developers I had a big inferiority complex towards the &amp;ldquo;grown up&amp;rdquo; Java developers and was studying at night to learn Java.&amp;nbsp; I immediately saw that Java didn&amp;rsquo;t have an equivalent to the old ADO Recordset* object and I couldn&amp;rsquo;t imagine how you could possibly code efficiently without it.&amp;nbsp; I even tried to write a Recordset equivalent for a couple nights.&amp;nbsp; Sounds pretty silly, doesn&amp;rsquo;t it?&amp;nbsp; I equated &amp;ldquo;productivity&amp;rdquo; with using that stupid old RecordSet object in VB6 and didn&amp;rsquo;t pay attention to the idiomatic ways that the Java guys got things done.&amp;nbsp; I should have been learning (early) Hibernate or TopLink and putting time into grokking OOP instead of complaining that I couldn&amp;rsquo;t do the old data centric style of development I knew from VB in Java.&lt;/p&gt;
&lt;p&gt;I see the same kind of shortsighted comparisons coming out over the past couple years.&amp;nbsp; The Entity Framework people are saying that EF is better than NHibernate because it has a designer cooked into VS.Net.&amp;nbsp; I would completely scoff at that because I don&amp;rsquo;t believe designers offer any productivity gains over the code centric way that I model and configure persistence.&amp;nbsp; On the other hand, I&amp;rsquo;d say that I think NHibernate is far superior to Entity Framework because Fluent NHibernate is far more powerful than EF&amp;rsquo;s new Code Only configuration model &amp;ndash; but the mainstream .Net world still equates productivity to visual tooling integrated into Visual Studio and wouldn&amp;rsquo;t buy that argument.&amp;nbsp; Either way, there&amp;rsquo;s danger in comparing &lt;b&gt;two tools that use different mechanisms to achieve the same ends&lt;/b&gt;.&amp;nbsp; Same thing applies to the &amp;ldquo;but MVC doesn&amp;rsquo;t have controls / data binding!&amp;rdquo; line of thought.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;* For you young&amp;rsquo;uns that grew up with .Net, in the VB6 days we didn&amp;rsquo;t have ORM&amp;rsquo;s or anything like the System.Collections namespace and we used the ol&amp;rsquo; ADODB.Recordset class as a Swiss army knife in our code.&amp;nbsp; It worked as well as you&amp;rsquo;re imagining it did.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;What is it that they know that you don&amp;rsquo;t know?&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;When you see somebody clinging hard to a position that you think is absolutely nuts, and you don&amp;rsquo;t think the other person is a bozo, you have to find out two different things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What does he know that I don&amp;rsquo;t know that leads him to that position?&lt;/li&gt;
&lt;li&gt;What doesn&amp;rsquo;t he know that would change his seemingly crazy position?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note to self, I should probably follow this one a little bit more.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;&amp;ldquo;Same ol&amp;rsquo;Stuff, Different Name&amp;rdquo;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Last year my son and I went up to Ft Worth to visit my favorite uncle who&amp;rsquo;s spent thirty odd years working in software as a systems analyst.&amp;nbsp; He said something to me that absolutely shook me to the core.&amp;nbsp; Paraphrasing, he said that &amp;ldquo;the problem with getting older is it&amp;rsquo;s harder to grasp new ideas.&amp;nbsp; More experienced people will tend to try to understand new ideas by their similarities to their old ideas, and by doing this they completely miss the parts that *are* different.&amp;rdquo;&amp;nbsp; Think on that one for a minute.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll give you a couple examples.&amp;nbsp; I, and many other experienced TDD practitioners, blew off Behavior Driven Development for a few years because it really just seemed to be &amp;ldquo;Test Driven Development done well, but with &amp;lsquo;should&amp;rsquo; instead of &amp;lsquo;assert&amp;rsquo; in the tests.&amp;rdquo;&amp;nbsp; I was wrong.&amp;nbsp; I only saw the similarities to what I already knew and not the very important, but subtle, differences that make BDD shine.&amp;nbsp; I don&amp;rsquo;t particularly follow BDD to the letter, but the way BDD shifted test/spec organization to &amp;ldquo;context&amp;rdquo; instead of TDD&amp;rsquo;s class/method-centric organization is hugely advantageous in practice.&amp;nbsp; My development work has gone better since I finally saw the differences from TDD to BDD. &lt;/p&gt;
&lt;p&gt;Another example.&amp;nbsp; I worked with an older fellow several years ago who told me that he finally got TDD when he realized that &amp;ldquo;it was just what I&amp;rsquo;ve been doing all these years with a new, fancy name.&amp;rdquo;&amp;nbsp; I don&amp;rsquo;t know what &amp;ldquo;the way he&amp;rsquo;d always done it&amp;rdquo; was, but he most certainly was not doing Test Driven Development in any way that actually helped him build software.&amp;nbsp; He was not using tests to drive the design.&amp;nbsp; He was putting a pretty elaborate design together first, then trying to retrofit some integration tests on at the backend.&amp;nbsp; It worked as badly as it always did.&amp;nbsp; He completely focused on the word &amp;ldquo;test&amp;rdquo; and missed the &amp;ldquo;driven&amp;rdquo; part that would have helped him design a better code structure.&lt;/p&gt;
&lt;p&gt;I came behind this guy and tore my hair out trying to extend and reshape that codebase for the next year.&amp;nbsp; My team&amp;rsquo;s efforts were very clearly frustrated and retarded by the poor design that could have been prevented if the previous team had understood Test Driven Development.&amp;nbsp; I wrote about my experiences with this system and the very real pain points we hit as the basis for &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/01/08/Orthogonal-Code.aspx"&gt;Orthogonal Code&lt;/a&gt;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Why you should learn &amp;ldquo;Shiny Objects&amp;rdquo;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;There&amp;rsquo;s a huge undercurrent of cynical grumpiness in software development about new things.&amp;nbsp; You know what I mean, the ol&amp;rsquo; &amp;ldquo;bah, that&amp;rsquo;s just the new shiny object the &amp;lsquo;cool&amp;rsquo; uber elitist geeks are playing with.&amp;rdquo;&amp;nbsp; You can&amp;rsquo;t learn everything in software and we&amp;rsquo;re terrible about self identifying way too much with the tools we do use, so it&amp;rsquo;s easy to get defensive when people start to get excited about something that you don&amp;rsquo;t use.&amp;nbsp; While chasing every little fad will definitely make you tired, I think you really, really need to pay attention to the new shiny objects &amp;ndash; especially when smart people you respect are the ones being excited.&amp;nbsp; My point is, if you see a lot of people speaking very favorably about a new thing, pay attention to it because it might be something that&amp;rsquo;s advantageous to you.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve largely ignored Git and distributed version control systems over the last couple years.&amp;nbsp; After all, Subversion wasn&amp;rsquo;t really my pain point and I still don&amp;rsquo;t think the move from SVN to Git is fractionally as big a deal as moving from VSS or CVS to Subversion was 5 years ago.&amp;nbsp; However, we started using it for FubuMVC development and now that I&amp;rsquo;ve gotten just a taste of Git&amp;rsquo;s branching workflow I can see obvious advantages. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Lots of Useful Systems have been built without your &amp;ldquo;Shiny Object!&amp;rdquo;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;I see some derivation of &amp;ldquo;lots of good, useful systems have been built without TDD/SOLID/CI/BDD/DDD/XP/OOP/Mock Objects/etc!&amp;rdquo;&amp;nbsp; Well, yeah.&amp;nbsp; You can build a system with almost any Turing complete language, but so what?&amp;nbsp; Do you still use Fortran?&amp;nbsp; Using that line to blow off a new or different idea is completely unproductive.&amp;nbsp; The real question is &amp;ldquo;could using this new thing help us do even better?&amp;rdquo;&amp;nbsp; The most successful project I worked on did not use any of those acronyms, but I fully believe that if I had to do that little project again today I could build it much, much faster with fewer resources and much less stress.&amp;nbsp; Success was good.&amp;nbsp; Success with lower stress would have been much better.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Aha!&amp;nbsp; Your Shiny new object is not a Silver Bullet!&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;ldquo;Silver Bullet&amp;rdquo; is the most overused phrase in all of software development.&amp;nbsp; Ha, ha, you use TDD and you still have some bugs/design flaws, therefore TDD isn&amp;rsquo;t a silver bullet and I won&amp;rsquo;t use it!&amp;nbsp; No, you&amp;rsquo;re not going to get a 10X productivity gain from any tool or technique, but a 5-10% increase in productivity is a worthwhile investment in my book.&amp;nbsp; At this point, if you use the phrase &amp;ldquo;well, it&amp;rsquo;s not a Silver Bullet&amp;rdquo; you&amp;rsquo;re either being sloppy in your thinking or just very cliched.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Diversity in Our Ecosystem is Good&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;m seeing a lot of people in the .Net community moaning the fact that there are just too many darn tools out there that seem to do the same thing.&amp;nbsp; Our FubuMVC project in specific has been blasted as just &amp;ldquo;Not Invented Here&amp;rdquo; syndrome gone amuck.&amp;nbsp; IoC tools are everywhere and they *do* have a lot of overlap (for the record, StructureMap was released before all the others &amp;ndash; but I mostly neglected it for years).&amp;nbsp; It&amp;rsquo;s an absurd argument.&amp;nbsp; Diversity is good.&amp;nbsp; I&amp;rsquo;ve taken features from AutoFac and Ninject before and even one from Unity a couple years back.&amp;nbsp; Windsor is adding a pretty significant diagnostics feature inspired by StructureMap.&amp;nbsp; Diversity is a good thing.&amp;nbsp; More people innovating means more innovation.&amp;nbsp; Bad ideas get junked when better ones appear.&amp;nbsp; Not every system is exactly the same.&amp;nbsp; Different approaches to the same old problems can frequently lead to new opportunities.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Why don&amp;rsquo;t you just jump ship to some other platform?&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;I hear this one all the time and it&amp;rsquo;s a good question in a way.&amp;nbsp; I like and/or use very, very little of the tooling from Microsoft beyond the CLR, C#, and the bare bones of Visual Studio.&amp;nbsp; I&amp;rsquo;m unapologetically a &amp;ldquo;Fowlbot&amp;rdquo; (arguably &amp;ldquo;ALT.NET&amp;rdquo; is simply the moniker for people who share roughly that same set of preferences and happen to work with .Net) and I have a certain aesthetic to software development that&amp;rsquo;s completely different than the prevailing philosophy of mainstream .Net.&amp;nbsp; I started this section, but I don&amp;rsquo;t particularly have a great answer other than inertia.&amp;nbsp; Switching to Java isn&amp;rsquo;t an answer (coding in Xml) and I haven&amp;rsquo;t particularly had opportunities to move to Ruby or Python.&amp;nbsp; I&amp;rsquo;m very entrenched with OSS development in .Net and our customers really want tooling in .Net as opposed to Ruby.&amp;nbsp; I do think there&amp;rsquo;s been a lot of improvement in the .Net space over the past three years that&amp;rsquo;s even unique to .Net.&amp;nbsp; Our OSS tools are improving dramatically (finally) and it&amp;rsquo;s kinda fun to be a part of that.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Okay, how about this one:&amp;nbsp; I&amp;rsquo;m very happy with what I&amp;rsquo;m doing at the moment.&amp;nbsp; Let&amp;rsquo;s call that good enough and move on&amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Let&amp;rsquo;s shelve WebForms v. MVC for now&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;I think the WebForms vs. MVC (paradigm here, not ASP.Net MVC) argument has exceeded its usefulness.&amp;nbsp; I think there&amp;rsquo;s plenty of misconceptions from the WebForms world towards MVC that could be dispelled (how to do screen synchronization without databound controls, why it&amp;rsquo;s more than just the testability concern where MVC shines), but all of the real arguments both pro and con are out there for anybody who cares enough to use Google to find them.&amp;nbsp; We&amp;rsquo;re at the point where I think everything&amp;rsquo;s been said and written.&amp;nbsp; I really don&amp;rsquo;t see people with entrenched positions changing their mind at this point, so can we put this argument on the backburner permanently and just agree to disagree?&amp;nbsp; Let&amp;rsquo;s put the energy we&amp;rsquo;re wasting arguing with the pro-WebForms folks and put it into making a better MVC ecosystem for .Net.&amp;nbsp; Besides, there are so very few examples out there on the web that even show how MVC can be productive.&amp;nbsp; Go fill that gap and leave the WebForms people alone for now.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;&amp;ldquo;Lazy loading can destroy performance&amp;rdquo;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Saw this statement while doing research for this post from somebody in the pro-EF camp who was apologizing for EF1&amp;rsquo;s insane strategy for &amp;ldquo;lazy loading.&amp;rdquo;&amp;nbsp; Guess what?&amp;nbsp; Sometimes &lt;b&gt;not&lt;/b&gt; doing lazy loading can destroy performance.&amp;nbsp; Case by case basis, folks.&amp;nbsp; To all you EF folks, you&amp;rsquo;ve just entered a brave new world.&amp;nbsp; You might want to learn from the experiences of the previous ORM tools &amp;ndash; and understanding when and where to use lazy or eager fetching is key.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=605551" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/Ranting/default.aspx">Ranting</category></item><item><title>If your API is confusing, change it!</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/21/if-your-api-is-confusing-change-it.aspx</link><pubDate>Thu, 21 Jan 2010 14:36:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:605409</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>13</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=605409</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/21/if-your-api-is-confusing-change-it.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://ayende.com/Blog/archive/2010/01/21/when-the-design-violates-the-principle-of-least-surprise-you.aspx"&gt;http://ayende.com/Blog/archive/2010/01/21/when-the-design-violates-the-principle-of-least-surprise-you.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The MVC team really needs to go back and iterate on their validation
design and rethink it -- and frankly, they need to have the courage to
challenge their approach and maybe even to break backwards
compatibility with the preview/CTP/beta/whatever they are&amp;#39;s if that&amp;#39;s
what it takes to make a better solution. &lt;/p&gt;
&lt;p&gt;As an API designer, if your users are having consistent trouble with using part of your API, then &lt;b&gt;your API is wrong&lt;/b&gt;.&amp;nbsp; Don&amp;#39;t try to beat it with just documentation or &amp;quot;user education.&amp;quot;&amp;nbsp; Go.&amp;nbsp; Change.&amp;nbsp; Your.&amp;nbsp; API.&amp;nbsp; To something that does work and makes your support queue slow down.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The dumbest thing I ever did in StructureMap was something called the &amp;quot;StructureMapConfiguration&amp;quot; static class where everything had to be done in a certain, non-obvious order.&amp;nbsp; The best thing I ever did in StructureMap was to deprecate, replace it with a better API, it then kill it.&amp;nbsp; I get worlds of support questions, but at least *that* issue went away.&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=605409" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/Ranting/default.aspx">Ranting</category></item><item><title>How Dovetail is using TopShelf</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/20/how-dovetail-is-using-topshelf.aspx</link><pubDate>Wed, 20 Jan 2010 21:40:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:600332</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>1</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=600332</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/20/how-dovetail-is-using-topshelf.aspx#comments</comments><description>&lt;p&gt;If you haven&amp;#39;t looked at the &lt;a href="http://code.google.com/p/topshelf/"&gt;TopShelf&lt;/a&gt; project from my buddy &lt;a href="http://codebetter.com/blogs/dru.sellers/"&gt;Dru Sellers&lt;/a&gt; for quickly standing up windows services, you might want to.&amp;nbsp; My coworker &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller"&gt;Kevin Miller&lt;/a&gt; has a couple blog posts up about how he&amp;#39;s using TopShelf:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2010/01/20/controlling-application-lifetime-in-topshelf.aspx"&gt;Controlling Application Lifetime in TopShelf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2010/01/20/configuring-topshelf-using-a-structuremap-container.aspx"&gt;Configuring TopShelf using a StructureMap Container&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=600332" width="1" height="1"&gt;</description></item><item><title>Slide Deck from Advanced Presentation Patterns at CodeMash</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/14/slide-deck-from-advanced-presentation-patterns-at-codemash.aspx</link><pubDate>Thu, 14 Jan 2010 11:54:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:587202</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>0</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=587202</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/14/slide-deck-from-advanced-presentation-patterns-at-codemash.aspx#comments</comments><description>&lt;p&gt;Since I had the request for this, the &lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/Advanced-Presentation-Patterns.zip"&gt;slide deck that I used yesterday at CodeMash in my marathon talk on Advanced Presentation Patterns is here&lt;/a&gt;.&amp;nbsp; There&amp;#39;s more links, but I&amp;#39;d first like to thank everybody who attended yesterday and especially those masochists of you who stuck out all four hours.&amp;nbsp; It was a great crowd, lots of good questions that made my job much easier.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;As I told many, many people who asked yesterday, I&amp;#39;m still writing the book, I&amp;#39;m not doing very well, but maybe the CodeMash session yesterday gets me back to usefulness.&lt;/p&gt;
&lt;p&gt;Now, links!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.jeremydmiller.com/ppatterns/"&gt;My book Wiki for Presentation Patterns&lt;/a&gt; (more content coming soon)&lt;/p&gt;
&lt;p&gt;&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; -- the original source for much of this work&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc707819.aspx"&gt;Prism -- Microsoft P&amp;amp;P&amp;#39;s guidance on &amp;quot;composite&amp;quot; applications&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeplex.com/caliburn"&gt;Caliburn -- Open Source Framework for WPF clients&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=2&amp;amp;ved=0CAoQFjAB&amp;amp;url=http%3A%2F%2Fwww.wirfs-brock.com%2FPDFs%2FA_Brief-Tour-of-RDD.pdf&amp;amp;ei=AAhPS_ytI4P0NaDrvIQJ&amp;amp;usg=AFQjCNH9r-WjWomwZ3Fm2tIls5wk6ySQ0Q&amp;amp;sig2=qDbsSZDOl6ZO6RezHUh-sA"&gt;A Brief Tour of Responsibility Driven Design&lt;/a&gt; -- Read this if you design software or want to.&amp;nbsp; Seriously.&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=587202" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/Design+Patterns/default.aspx">Design Patterns</category><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/Presentation+Patterns/default.aspx">Presentation Patterns</category></item><item><title>Patterns in Practice:  A Retrospective</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/11/patterns-in-practice-a-retrospective.aspx</link><pubDate>Mon, 11 Jan 2010 12:43:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:580595</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>17</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=580595</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/11/patterns-in-practice-a-retrospective.aspx#comments</comments><description>&lt;p&gt;For most of the past two years I&amp;rsquo;ve written the &amp;ldquo;&lt;a href="http://msdn.microsoft.com/en-us/magazine/ee532402.aspx?sdmr=patternsinpractice&amp;amp;sdmi=columns"&gt;Patterns in Practice&lt;/a&gt;&amp;rdquo; column in MSDN magazine.&amp;nbsp; The January issue contained &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2010/01/06/writing-internal-dsl-s-in-msdn.aspx"&gt;my last article&lt;/a&gt; and I thought it&amp;rsquo;d be good to write a little retrospective on the series.&amp;nbsp; It&amp;rsquo;s probably been a good opportunity for me and it seemed to be mostly well received (it&amp;rsquo;s not as much fun as blogging because you just don&amp;rsquo;t get as much immediate feedback, good or bad).&amp;nbsp; CodeBetter has always been frequented by a self-selected group (you can&amp;rsquo;t call it an echo chamber because of the way we argue) of developers who were already learning about Agile practices and the old software design concepts passed down to us from the &amp;ldquo;Gang of Four,&amp;rdquo; the Smalltalk world, and Uncle Bob&amp;rsquo;s SOLID writings from the 90&amp;rsquo;s.&amp;nbsp; The MSDN column has been nice in that it allowed me to write about some of these design concepts for a more mainstream audience who might not have as much exposure to these ideas.&amp;nbsp; Whether that worked or not, or made the slightest bit of impact, who knows?&amp;nbsp; It did pay for the down payment on my new car last year (and a root canal), so it&amp;rsquo;s all good to me;)&lt;/p&gt;
&lt;p&gt;Some folks are going to argue that &lt;a href="http://blog.objectmentor.com/articles/2009/01/31/quality-doesnt-matter-that-much-jeff-and-joel"&gt;&amp;ldquo;software quality&amp;rdquo; doesn&amp;rsquo;t matter&lt;/a&gt;* because it&amp;rsquo;s really all about whether or not you&amp;rsquo;re building the right system with the right business plan.&amp;nbsp; Let&amp;rsquo;s assume right now that you&amp;rsquo;ve got the right business plan, good requirements, and even decent collaboration from your business partners (and manna streaming down from the ceilings whenever you get hungry at work because that&amp;rsquo;s just as likely as the preceding list).&amp;nbsp; You&amp;rsquo;ve still got to execute the project &amp;ndash; and you probably aren&amp;rsquo;t going to build it all in one quick pass.&amp;nbsp; You&amp;rsquo;re going to build it incrementally.&amp;nbsp; You&amp;rsquo;re going to make mistakes, fix mistakes, and iterate (even if you&amp;rsquo;re working a theoretical waterfall).&amp;nbsp; Bad designs and bad code will slow your team down and delay your all important time to market.&amp;nbsp; Let&amp;rsquo;s be realistic here, you never have the perfect requirements.&amp;nbsp; Your business partners with the vision will need to iterate and refine their vision, and the entire product team is better off if the development team is technically able to efficiently deliver features that weren&amp;rsquo;t even imagined at project inception.&amp;nbsp; You can succeed with bad code, but all things being equal, I think you maximize your business&amp;rsquo;s chances of succeeding by taking software quality very seriously.&lt;/p&gt;
&lt;p&gt;First off, let&amp;rsquo;s make the assumption that your software design really does matter.&amp;nbsp; It matters not because of ALT.NET or Software Craftmanship or Design Pattern purity, but because &amp;ldquo;good&amp;rdquo; code structures help development teams be productive now and over time while &amp;ldquo;bad&amp;rdquo; code structures bind a team up with &amp;ldquo;&lt;a href="http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf"&gt;code viscosity&lt;/a&gt;.&amp;rdquo;&amp;nbsp; Let me be very clear here, I&amp;rsquo;m &lt;b&gt;defining software quality as the structural qualities of code structure that enable a team to be productive within that codebase for an extended amount of time&lt;/b&gt;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been studying software design seriously for over a decade and building software for longer than that.&amp;nbsp; I&amp;rsquo;ve seen the exact same team founder in one codebase and generally succeed in another codebase.&amp;nbsp; I&amp;rsquo;ve worked in some codebases that felt like I was as light as a feather and functionality flowed into the system as fast as I could type.&amp;nbsp; I&amp;rsquo;ve worked in other systems where I wanted to tear my hair out because of how much work it took to do even simple seeming things.&amp;nbsp; Why were some codebases good and others pure frustration?&amp;nbsp; Offhand, I&amp;rsquo;ll give you five qualities or themes that separated the good codebases from the bad (not an exhaustive list of course):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/01/08/Orthogonal-Code.aspx"&gt;Orthogonality&lt;/a&gt;.&amp;nbsp; It&amp;rsquo;s a fancy word that just means being able to do or change or exercise one thing at a time.&amp;nbsp; It also means being able to understand or learn about one thing at a time in a system.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/02/10/first-causes-reversibility.aspx"&gt;Reversibility&lt;/a&gt;.&amp;nbsp; Technical or requirement decisions don&amp;rsquo;t have to be locked in stone.&lt;/li&gt;
&lt;li&gt;Feedback.&amp;nbsp; I think the best way to be successful building software is to assume that everything you do is wrong.&amp;nbsp; We need rapid feedback cycles to find and correct our inevitable mistakes.&lt;/li&gt;
&lt;li&gt;Iteration.&amp;nbsp; Your first idea is never your best idea.&amp;nbsp; Your business partners will need to refine their vision.&amp;nbsp; You need to be able to respond to both negative and positive feedback.&lt;/li&gt;
&lt;li&gt;Minimal Duplication.&amp;nbsp; Less duplication means easier change, less chance of making silly errors, and quicker iteration to get to the best product&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are the main themes in Patterns in Practice that I think are important.&amp;nbsp; Many of the design concepts like Design Patterns, the SOLID Principles, the GRASP Patterns, Code Smells, or the tools in Responsibility Driven Design are nothing but heuristics to help guide you to designs that exhibit the qualities I enumerated above or detect the absence of these qualities.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you ask me what the essence of a good software&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/1b5b7e52-a263-43a5-b42d-60120d2fbbbd"&gt;The Open Closed Principle&lt;/a&gt;.&amp;nbsp; The &amp;ldquo;O&amp;rdquo; in SOLID.&amp;nbsp; Think about this question for a minute, what&amp;rsquo;s generally more productive for your team, writing all new code or breaking into the middle of existing code to make changes?&amp;nbsp; Which is more risky in terms of bugs and introducing cute new regression bugs?&amp;nbsp; Do you like having to trace through existing code to find the place to break in to change it, or starting from a fresh slate?&amp;nbsp; If you answered my loaded questions correctly, you sir or madam, are interested in learning about the Open Closed Principle as a &lt;i&gt;design goal.&amp;nbsp; &lt;/i&gt;If you think the OCP just means having interfaces and plugin points for everything, then you need to read this article because that&amp;rsquo;s not the point.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/65cf290a-722b-4d15-8547-f996b2fbac73"&gt;Object Role Stereotypes&lt;/a&gt;.&amp;nbsp; I&amp;rsquo;ve said many times that I think Responsibility Driven Design is one of the most valuable, yet overlooked design techniques you can possibly add to your design toolbox.&amp;nbsp; In the article on the Open Closed Principle I also mentioned the all important &amp;ldquo;Single Responsibility Principle&amp;rdquo; that more or less states that a class should have one and only one reason to change.&amp;nbsp; Great, but what&amp;rsquo;s a responsibility?&amp;nbsp; Object Role Stereotypes are a fantastic mental tool to help you understand and delineate the responsibilities within a design problem.&amp;nbsp; The research that I did in writing this article led to some significant architectural changes to StructureMap that opened up a lot of opportunities for extending and improving StructureMap.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/6cff5c56-3b3c-47db-9856-b8f9f44bc892"&gt;Cohesion And Coupling&lt;/a&gt;.&amp;nbsp; An explanation of what Orthogonality is and the practical impact of it on your code.&amp;nbsp; If you&amp;rsquo;re starting from ground zero in software design, I think the first two concepts you need to understand are cohesion and coupling.&amp;nbsp; Arguably, almost every design concept and tool in the whole Patterns in Practice series is about increasing cohesion and minimizing harmful coupling in your code.&amp;nbsp; It&amp;rsquo;s very important that you understand the impact of coupling in your code.&amp;nbsp; Know when it&amp;rsquo;s harmful coupling you should eliminate or relatively harmless coupling that would do more harm than good to abstract away.&amp;nbsp; A lot of harm is done in software development today due to zealous attempts to reduce coupling.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/fb7574f6-98cd-4dc6-9492-ef2a61d60ac5"&gt;Design For Testability&lt;/a&gt;.&amp;nbsp; It&amp;rsquo;s all about rapid feedback cycles and the ability to iterate.&amp;nbsp; How quickly can you go from doing something in your code to knowing that something was done correctly so you can turn your back on it?&amp;nbsp; It&amp;rsquo;s arguably just another way to think through the orthogonality of your architecture.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/9c9ce963-982e-4dd5-bf99-9621df7ae83d"&gt;Convention Over Configuration&lt;/a&gt;.&amp;nbsp; A design concept made popular in Ruby on Rails but increasingly important in .Net circles.&amp;nbsp; It&amp;rsquo;s a way to shrink your codebase down and to eliminate unnecessary duplication of &amp;ldquo;facts&amp;rdquo; in your system.&amp;nbsp; Makes iteration cheaper.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/7f4528c1-a52d-454e-af38-bdbbff8c1155"&gt;Persistence Patterns&lt;/a&gt;.&amp;nbsp; I wasn&amp;rsquo;t particularly inspired by this topic, but hey, it&amp;rsquo;s valuable stuff to know if you&amp;rsquo;re going to use ORM&amp;rsquo;s.&amp;nbsp; NHibernate or Entity Framework users really need to understand these concepts to avoid some ugly pitfalls. At a minimum, make sure you understand what lazy loading and virtual proxies are all about.&amp;nbsp; Besides, it&amp;rsquo;s nice to understand what&amp;rsquo;s going on under the covers.&amp;nbsp; Once in a while you may want to use these patterns in your own code.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/3ae65c7a-edde-4d67-8887-53d0533390b8"&gt;The Unit Of Work Pattern And Persistence Ignorance&lt;/a&gt;.&amp;nbsp; I continued the discussion on Persistence Patterns and tried to explain what and why &amp;ldquo;Persistence Ignorance&amp;rdquo; is important and the real impact of persistence framework on your development efforts.&amp;nbsp; Judging from the recent blog posts from the Entity Framework on their new EF4 POCO implementation, they probably didn&amp;rsquo;t do more than skim this issue.&amp;nbsp; Okay, maybe that&amp;rsquo;s not fair, but if you read this article you might understand why I don&amp;rsquo;t think Entity Framework has really arrived as a viable option for me despite the dramatic improvements from EF1 to EF4.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc62b960-dcb5-42ef-90cd-98c779315a11"&gt;Incremental Delivery Through Continuous Design&lt;/a&gt;.&amp;nbsp; I can&amp;rsquo;t believe Howard let me get away with this one because I was specifically not to proselytize Agile development.&amp;nbsp; I tried to discuss the business value of being able to deliver incrementally and flexibly, then discussed the specific design issues supporting incremental delivery.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/879c949e-5be3-416d-a883-483d72f3eeda"&gt;Functional Programming for Everyday .NET Developers&lt;/a&gt;.&amp;nbsp; I learned a lot from writing this one.&amp;nbsp; I think that adding some functional programming techniques to my day to day coding has been very beneficial to my efforts.&amp;nbsp; In a lot of ways, FP usage can help reduce duplication by giving you a more fine grained mechanism for composition than OOP does and passing first class functions around often increases encapsulation of classes.&amp;nbsp; Continuation Passing Style is close to a daily technique for me now. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/f16b541c-788a-43a3-8b75-061186fa777b"&gt;Internal Domain Specific Languages&lt;/a&gt;.&amp;nbsp; Don&amp;rsquo;t assume that DSL means Oslo or whatever Whitehorse ended up becoming.&amp;nbsp; If you are interested in exploring the usage of Fluent Interfaces in your own architecture without a meltdown, here&amp;rsquo;s some design patterns to help you get started.&amp;nbsp; I think I could easily argue that articles 1-8 contained some bit of material that could help the average software team.&amp;nbsp; This one was just what *I* wanted to write about, so there.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;The Future&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;m thoroughly burnt out on this for now and I&amp;rsquo;m distressingly behind on my book and mired in OSS project obligations.&amp;nbsp; I&amp;rsquo;m not touching it again for at least 6-9 months.&amp;nbsp; If I do start it up again, I think I want to focus on really basic concepts of OOP.&amp;nbsp; It&amp;rsquo;s my belief from 12+ years of development experience that the mass majority of developers, even &amp;ldquo;experienced&amp;rdquo; developers, cannot use object oriented programming or functional programming to their advantage.&amp;nbsp; I betcha that most .Net developers can give me a textbook glossary of OO terms like inheritance and polymorphism, but most of them probably don&amp;rsquo;t use these concepts in a way that &lt;b&gt;helps&lt;/b&gt; them get work done.&amp;nbsp; It&amp;rsquo;s also my belief that most developers just never move beyond brute force procedural programming techniques.&amp;nbsp; If there ever is a next article, I&amp;rsquo;m tackling the &amp;ldquo;Anti-If&amp;rdquo; campaign with some basic Design Pattern usages to streamline your code by eliminating if/then branching code. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;* Okay, I think you could argue with me that code quality doesn&amp;rsquo;t matter on small projects or projects that would be easier to rewrite later when and if they do need to change.&amp;nbsp; The only problem with that statement is that I&amp;rsquo;ve seen truly awful messes happen when those &amp;ldquo;throwaway&amp;rdquo; systems uncontrollably grew over time into big monsters.&amp;nbsp; My advice is to strive to reach a level of &amp;ldquo;&lt;a href="http://en.wikipedia.org/wiki/Four_stages_of_competence"&gt;unconscious competence&lt;/a&gt;&amp;rdquo; to where you naturally write high quality code and designs without going out of your way. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=580595" width="1" height="1"&gt;</description></item><item><title>"Hello, World" in FubuMVC</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/08/quot-hello-world-quot-in-fubumvc.aspx</link><pubDate>Fri, 08 Jan 2010 15:57:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:579553</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>4</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=579553</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/08/quot-hello-world-quot-in-fubumvc.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s raw and unformed (Fubu, not the blog post), but here&amp;#39;s the first &amp;quot;Hello, World&amp;quot; sample for the &lt;a href="http://blog.timtyrrell.net/2010/01/hello-world-with-fubumvc-super-quick.html?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+timtyrrell+%28Tim+Tyrrell%27s+%28Mostly%29+.NET+Blog%29"&gt;Fubu Reboot from Dovetail&amp;#39;s very own Tim Tyrell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the things the Fubu team is definitely talking about is some app starter kits ala Rails &amp;quot;rails [project name] create&amp;quot; that lays down a basic structure.&amp;nbsp; Another &amp;quot;getting started&amp;quot; feature that doesn&amp;#39;t exist is a set of OOTB conventions so you can get going with:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;public class MyFubuRegistry : FubuRegistry&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public MyFubuRegistry()&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UseBasicConventions();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=579553" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx">FubuMVC</category></item><item><title>Call for FubuMVC Contributors</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/07/call-for-fubumvc-contributors.aspx</link><pubDate>Thu, 07 Jan 2010 16:39:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:578990</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>1</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=578990</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/07/call-for-fubumvc-contributors.aspx#comments</comments><description>&lt;p&gt;Chad just put up a &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2010/01/07/announcing-fubumvc.aspx"&gt;post on how you can get involved with the FubuMVC project&lt;/a&gt;.&amp;nbsp; We&amp;#39;ve got the website and Wiki going and the mailing list, but we&amp;#39;re not hugely organized yet.&amp;nbsp; At this point I feel like there&amp;#39;s enough working to say that the project has a lot of promise down the road.&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=578990" width="1" height="1"&gt;</description><category domain="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx">FubuMVC</category></item><item><title>Writing Internal DSL's in MSDN</title><link>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/06/writing-internal-dsl-s-in-msdn.aspx</link><pubDate>Thu, 07 Jan 2010 03:37:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:578732</guid><dc:creator>Jeremy D. Miller</dc:creator><slash:comments>5</slash:comments><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://codebetter.com/blogs/jeremy.miller/commentapi.aspx?PostID=578732</wfw:comment><comments>http://codebetter.com/blogs/jeremy.miller/archive/2010/01/06/writing-internal-dsl-s-in-msdn.aspx#comments</comments><description>&lt;p&gt;My latest and last (for the moment anyway) article for MSDN just went up today.&amp;nbsp; This time I tackled the design patterns and strategies for building &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee291514.aspx"&gt;Internal Domain Specific Languages&lt;/a&gt;.&amp;nbsp; At least in the .Net space, the mainstream folks seem to hear &amp;quot;DSL&amp;quot; and only think about big efforts to create business facing languages with external DSL tools like Oslo -- probably because that&amp;#39;s been their first exposure to the idea of DSL&amp;#39;s.&amp;nbsp; That stuff is valuable in places, but don&amp;#39;t overlook the value in creating small mini-languages inside your everyday programming language for developer related tasks.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Mini-language or &lt;a href="http://martinfowler.com/dslwip/InternalOverview.html"&gt;Internal DSL&lt;/a&gt;&amp;#39;s may be a misnomer in this case.&amp;nbsp; All you&amp;#39;re really attempting to do is to create a more usable form of API that ends up being more readable and quicker to specify than the standard &amp;quot;push button&amp;quot; API.&amp;nbsp; You see more and more examples of these little internal DSL&amp;#39;s in open source tools like Fluent NHibernate, StructureMap, Windsor, and AutoMapper.&amp;nbsp; Now even Microsoft is dabbling in mini-languages with the &amp;quot;Code Only&amp;quot; configuration option in Entity Framework 4 (which at a glance seems determined to replicate every single mistake that Fluent NHibernate made early on).&lt;/p&gt;
&lt;p&gt;I&amp;#39;d hoped to include much more writing on this topic in my blog, but I&amp;#39;m a bit burnt out at the moment.&amp;nbsp; At some point in the next month I&amp;#39;d like to write up my lessons learned with the StructureMap Registry DSL and how it&amp;#39;s evolved over the past three years to improve its usability, the problems users have had, dumping the &amp;quot;English like&amp;quot; syntax in favor of something terser, and how I build the DSL stuff.&amp;nbsp; Also, I&amp;#39;d like to explain the &amp;quot;Object Scoping&amp;quot; pattern that got cut from this article.&amp;nbsp; Lastly, I&amp;#39;ve got a little Internal DSL we use at Dovetail for user action routing that I think would make a good, approachable example.&amp;nbsp; I&amp;#39;m on a bit of a New Year&amp;#39;s Resolution to spit out more (any) blog content.&lt;/p&gt;
&lt;p&gt;Lastly, I&amp;#39;d like to write up a retrospective on the whole Patterns in Practice column I&amp;#39;ve been writing for the past two years.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The pattern names for the article and much, much more information were drawn from Martin Fowler&amp;#39;s online draft for his DSL book at &lt;a href="http://martinfowler.com/dslwip/"&gt;http://martinfowler.com/dslwip/&lt;/a&gt;.&amp;nbsp; I&amp;#39;d heartily recommend perusing the site if you&amp;#39;re interested in DSL development at all.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=578732" width="1" height="1"&gt;</description></item></channel></rss>