<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://codebetter.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Jeremy D. Miller -- The Shade Tree Developer</title><subtitle type="html">Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

</subtitle><id>http://codebetter.com/blogs/jeremy.miller/atom.aspx</id><link rel="alternate" type="text/html" href="http://codebetter.com/blogs/jeremy.miller/default.aspx" /><link rel="self" type="application/atom+xml" href="http://codebetter.com/blogs/jeremy.miller/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2010-01-29T16:17:00Z</updated><entry><title>Your chance to heckle me on Ignite your Coding tomorrow</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/03/17/your-chance-to-heckle-me-on-ignite-your-coding-tomorrow.aspx" /><id>/blogs/jeremy.miller/archive/2010/03/17/your-chance-to-heckle-me-on-ignite-your-coding-tomorrow.aspx</id><published>2010-03-18T02:06:00Z</published><updated>2010-03-18T02:06:00Z</updated><content type="html">&lt;p&gt;It&amp;#39;s my turn next to talk and try to field questions on the new &lt;a href="http://msdn.microsoft.com/en-ca/ff182908.aspx"&gt;Ignite your Coding&lt;/a&gt; podcast tomorrow.&amp;nbsp; It&amp;#39;s a little bit different format where you can join the NetMeeting and jump right into the conversation.&amp;nbsp; I&amp;#39;m going to be talking about the whole &amp;quot;Essence vs. Ceremony&amp;quot; discussion and all the ways we can pack more punch with less code.&amp;nbsp; I want to talk about the newer convention based programming techniques that are popping up everywhere in the newer open source projects in .Net, building and using DSL&amp;#39;s in the wild, and techniques for &amp;quot;DRY-ing&amp;quot; up your .Net code.&amp;nbsp; I hope you&amp;#39;ll tune it, because I&amp;#39;m a vastly better speaker when I&amp;#39;m getting a lot of questions and even backtalk;-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=688258" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="Blatant Self Promotion" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/Blatant+Self+Promotion/default.aspx" /></entry><entry><title>How to know if you're a coding optimist or pessimist</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/03/15/how-to-know-if-you-re-a-coding-optimist-or-pessimist.aspx" /><id>/blogs/jeremy.miller/archive/2010/03/15/how-to-know-if-you-re-a-coding-optimist-or-pessimist.aspx</id><published>2010-03-16T01:39:00Z</published><updated>2010-03-16T01:39:00Z</updated><content type="html">&lt;p&gt;Let&amp;#39;s say you&amp;#39;re a developer -- and you probably are if you&amp;#39;re reading this.&amp;nbsp; How do you know if you have a generally sunny, optimistic set of mind or a gloomy, pessimistic attitude?&amp;nbsp; It&amp;#39;s very simple.&amp;nbsp; You know how you constantly look at 6 month old code and see a better way to rewrite the code?&amp;nbsp; An optimist rewrites that code and says &amp;quot;damn, the new code is so much cleaner!&amp;quot;&amp;nbsp; The pessimist rewrites the old code and says &amp;quot;damn, that old code sure was a mess.&amp;quot;&lt;/p&gt;
&lt;p&gt;And if you never find any thing wrong with your 6 month old code?&amp;nbsp; You sir are either severely lacking in retrospection and/or you might very well be &lt;a href="http://en.wikipedia.org/wiki/Four_stages_of_competence"&gt;unconsciously incompetent&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=682927" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author></entry><entry><title>Nice introduction to StructureMap</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/03/05/nice-introduction-to-structuremap.aspx" /><id>/blogs/jeremy.miller/archive/2010/03/05/nice-introduction-to-structuremap.aspx</id><published>2010-03-05T16:29:00Z</published><updated>2010-03-05T16:29:00Z</updated><content type="html">&lt;p&gt;Using StructureMap and the StructureMap AutoMocking library in the context of MS MVC:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.jorritsalverda.nl/2010/02/09/maintainable-mvc-series-inversion-of-control-container-structuremap/"&gt;http://blog.jorritsalverda.nl/2010/02/09/maintainable-mvc-series-inversion-of-control-container-structuremap/&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=664090" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="StructureMap" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/StructureMap/default.aspx" /></entry><entry><title>StoryTeller Video from Pablo's Fiesta</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/03/03/storyteller-video-from-pablo-s-fiesta.aspx" /><id>/blogs/jeremy.miller/archive/2010/03/03/storyteller-video-from-pablo-s-fiesta.aspx</id><published>2010-03-03T15:01:00Z</published><updated>2010-03-03T15:01:00Z</updated><content type="html">&lt;p&gt;I meant to write a summary of Pablo&amp;#39;s Fiesta, but the will to blog just isn&amp;#39;t there anymore.&amp;nbsp; Instead, here&amp;#39;s &lt;a href="http://vimeo.com/9881066"&gt;the video from the StoryTeller demo&lt;/a&gt; that Weston Binford roped me into.&amp;nbsp; I&amp;#39;m pushing very hard right now toward the StoryTeller 1.0 release.&amp;nbsp; I&amp;#39;m hoping to have it released -- with docs and examples -- by the end of March so I can get on to other things.&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=658748" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="StoryTeller" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/StoryTeller/default.aspx" /></entry><entry><title>A Vision for FubuMVC’s Component Model (gems, Nu, engines, slices, oh my…)</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/25/a-vision-for-fubumvc-s-component-model-gems-nu-engines-slices-oh-my.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/25/a-vision-for-fubumvc-s-component-model-gems-nu-engines-slices-oh-my.aspx</id><published>2010-02-25T15:46:00Z</published><updated>2010-02-25T15:46:00Z</updated><content type="html">&lt;p&gt;I&amp;rsquo;m banging this out fast and trying to think out loud.&amp;nbsp; Blame the lack of polish on that previous statement.&amp;nbsp; The whole point of this blog post is to elicit feedback and get ready for Pablo&amp;rsquo;s Fiesta this weekend (no crazy tax evader can stop the ALT.NET community by merely crashing a plane into the building).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://fiesta.lostechies.com/"&gt;Pablo&amp;rsquo;s Fiesta&lt;/a&gt; starts tomorrow night with the typical Open Spaces agenda creation.&amp;nbsp; Coincidentally, we&amp;rsquo;ve got several FubuMVC contributors coming into town and we&amp;rsquo;re going to take advantage of that to carry out some FubuMVC project business.&amp;nbsp; My main concern for the conference is to nail down our component story for FubuMVC.&amp;nbsp; First off, I want FubuMVC to have a fullblown &amp;ldquo;&lt;a href="http://rails-engines.org/"&gt;engine&lt;/a&gt;&amp;rdquo; or &amp;ldquo;&lt;a href="http://merbunity.com/news/11"&gt;slice&lt;/a&gt;&amp;rdquo; strategy that allows you to build and reuse vertical slices of an application across projects.&amp;nbsp; Secondly, we need an easy way to apply those &amp;ldquo;engines&amp;rdquo; to other places.&amp;nbsp; For those of you familiar with Rails and Merb, I&amp;rsquo;m wanting nothing less than a &amp;ldquo;&lt;a href="http://docs.rubygems.org/"&gt;gems&lt;/a&gt;&amp;rdquo; like solution for FubuMVC that allows a project team to quickly assemble project infrastructure and share substantial parts of an application architecture &lt;b&gt;with as little friction as possible.&lt;/b&gt;&amp;nbsp; Right now, my focus is on the resurrected &lt;a href="http://wiki.github.com/phatboyg/nu/"&gt;Nu project&lt;/a&gt; as a way to distribute and apply engines to your code tree packaged up as &amp;ldquo;Nug&amp;rsquo;s&amp;rdquo; (the Nu analogue to a gem). &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To really make the usage and distribution of FubuMVC &amp;ldquo;engines&amp;rdquo; go well, I think we need to do be able to package / discover / distribute the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Libraries.&amp;nbsp; &lt;/b&gt;One of the things I hear from people is that they just think it&amp;rsquo;s too hard to piece together OSS tools (it doesn&amp;rsquo;t matter if you disagree with that statement, because many people *do* feel that way).&amp;nbsp; The very first step is to finally get a decent .Net OSS story around distributing components.&amp;nbsp; I want something like &amp;ldquo;gems install fluent-nhibernate&amp;rdquo; that puts the latest released version of Fluent NHibernate into my &amp;ldquo;tools&amp;rdquo; directory, and oh yeah, also gets the correct NHibernate binaries with all the little Castle and LinFu pieces that live underneath NHibernate in one go.&amp;nbsp; This is obviously pretty complicated when you think about versioning and dependency trees, but it&amp;rsquo;s also been done in other development communities and we can take a lot of inspiration from things like gems, Maven, etc.
&lt;ul&gt;
&lt;li&gt;We&amp;rsquo;ll have to effectively agree upon a standard folder layout for external tools so that Nu can scan &lt;/li&gt;
&lt;li&gt;I&amp;rsquo;m fully aware of HornGet, but I do not see it as the right approach to this problem.&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Extensible Command Line tools&lt;/b&gt;.&amp;nbsp; We have several command line utilities at Dovetail for our localization subsystem (exporting/importing data, filling in missing localization keys, etc.) that could easily be useful on other projects.&amp;nbsp; Other folks are keen on building &amp;ldquo;scaffolding&amp;rdquo; approaches into Fubu&amp;nbsp;&amp;nbsp; Nu is built around extensible command line tools and I think it could be a powerful way to distribute little project utilities as part of an engine/Nug package.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Project Files&lt;/b&gt;.&amp;nbsp; I think it&amp;rsquo;d be nice if when I installed the (not yet existent) &amp;ldquo;NHibernate QuickKit&amp;rdquo; engine with Nu and Nu could reach into my *.csproj files and add the right references for me in order to use the NHibernate features.&amp;nbsp; That&amp;rsquo;s a big can of worms, but I think it could reduce friction in using a lot of tools &amp;ndash; especially tools that come with lots of assemblies (I&amp;rsquo;m looking at you nServiceBus).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Configuration&lt;/b&gt;.&amp;nbsp; Your engine could easily require some external configuration.&amp;nbsp; I know one of the first engines I&amp;rsquo;d like to see is a NHibernate starter kit that would give you a basic NHibernate setup and a simplistic Repository implementation &amp;ndash; and NHibernate just doesn&amp;rsquo;t go without a connection string somewhere.&amp;nbsp; My thought is to standardize FubuMVC on the AppSettingsProvider model that &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/07/12/how-we-handle-application-configuration.aspx"&gt;Josh blogged about here&lt;/a&gt;.&amp;nbsp; 
&lt;ul&gt;
&lt;li&gt;When a Nug is installed, maybe it could scan the new imported assemblies and find any new &amp;ldquo;Settings&amp;rdquo; classes needed for the new engine.&amp;nbsp; We could have it add the new properties to the appSettings file automatically with any default values.&amp;nbsp; I think this could help to make things like NHibernate integration easier&lt;/li&gt;
&lt;li&gt;The standardized configuration model for things like file paths, Url&amp;rsquo;s, and connection strings would make it easier to share deployment recipes and infrastructure for staging code through different environments (dev to test to UAT to production).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Services.&lt;/b&gt;&amp;nbsp; A slice/engine may easily need to expose other services to the underlying IoC engine.&amp;nbsp; Fubu can only function with an IoC container.&amp;nbsp;&amp;nbsp; It&amp;rsquo;s been a very important goal to me to ensure that Fubu is IoC tool agnostic (it&amp;rsquo;s not there yet, too many assumptions about StructureMap runtime characteristics that aren&amp;rsquo;t necessarily true of the other tools.&amp;nbsp; We&amp;rsquo;ll get there) and that Fubu makes no restrictions on *how* you can use your IoC tool (many of the &amp;ldquo;abstract away the IoC tool&amp;rdquo; strategies do an awful job on this score).&amp;nbsp; You already have some limited ability to register services in FubuRegistry.&amp;nbsp; The FubuRegistry.Include( other registry ) doesn&amp;rsquo;t merge the service registry yet, but will at some point.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Conventions&lt;/b&gt;.&amp;nbsp; Html conventions, behavior policies, Url/Route conventions, View conventions, you name it, all of it is reusable in FubuMVC.&amp;nbsp; I think it&amp;rsquo;d be nice to say &amp;ldquo;I wanna use the &amp;lsquo;DataAnnotations&amp;rsquo; pack&amp;rdquo; and just like that, you get Html conventions applied to your project that read metadata off of the DataAnnotation attributes and apply that towards client side jQuery validation.&amp;nbsp; Today this is done with code in a FubuRegistry class to explicitly add conventions. &lt;/li&gt;
&lt;li&gt;&lt;b&gt;JavaScript libraries&lt;/b&gt;.&amp;nbsp; Look, it&amp;rsquo;s a rich internet world now and you almost have to use Ajax to create a compelling user experience.&amp;nbsp; There&amp;rsquo;s the whole jQuery ecosystem with more useful plugins than you can shake a fist at.&amp;nbsp; However, a lot of these plugins (jqGrid comes to mind) require some server side integration to really shine.&amp;nbsp; What if your &amp;ldquo;Nug&amp;rsquo;s&amp;rdquo; could contain both server side functions and custom JavaScript libraries?&amp;nbsp; When you download a Nug, any Javascript libraries will be pushed to where the main Fubu app can find those libraries.&amp;nbsp; 
&lt;ul&gt;
&lt;li&gt;We have to determine a standard location for the JavaScript files&lt;/li&gt;
&lt;li&gt;We need some sort of script manager piece in FubuMVC.UI that can load them&lt;/li&gt;
&lt;li&gt;Maybe we minify them on demand?&lt;/li&gt;
&lt;li&gt;I think it would be nice if custom Html Helper from external engines could quietly declare behind the scenes that &amp;ldquo;I need this JS / CSS file&amp;rdquo; and a &amp;lt;script&amp;gt; tag is added to the page if it isn&amp;rsquo;t already there&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Packaged Views&lt;/b&gt;.&amp;nbsp; It would be nice is some engines could include packaged views for things like admin screens.&amp;nbsp; You can do this out of the box by using some sort of embedded views, but it&amp;rsquo;d probably be nice if we had a good way for an engine installation to copy the view files to a known location where you could modify or skin those views at will (in this case, the reusable view from the engine is mostly just a template).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Warmup / Deployment tools&lt;/b&gt;.&amp;nbsp; I&amp;rsquo;ve always admired things like Capistrano in the Ruby world.&amp;nbsp; If we standardized the FubuMVC code structure, maybe we could reuse project setup, automated build tooling, and deployment recipes across projects the way that Rails developers do.&amp;nbsp; Wouldn&amp;rsquo;t that be awesome.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Another architectural issue is how the externalized engines are discovered by FubuMVC.&amp;nbsp; Right now, you have to explicitly add things to a FubuRegistry class.&amp;nbsp; I think we also need to consider some sort of dynamic discovery of the external addin&amp;rsquo;s.&amp;nbsp; It could just be a known folder that we scan at application startup, a partial class in your top level web project that could be auto-generated, an Xml/Json file listing the class names of FubuRegistry types to load as engines or something else I haven&amp;rsquo;t considered yet.&amp;nbsp; I&amp;rsquo;m leaning towards the scanning model, but I&amp;rsquo;m all ears.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The core architectural philosophy of FubuMVC is composition.&amp;nbsp; It&amp;rsquo;s completely wrapped around IoC service composition, the code basically follows the S.O.L.I.D. ideas for object responsibilities so there&amp;rsquo;s a lot of seams, and everything is swappable (think &amp;ldquo;sharp tools&amp;rdquo;).&amp;nbsp; Conventions can be packaged up and reused across projects.&amp;nbsp; Vertical slices of the application can be packaged and reused across applications by the FubuRegistry concept.&amp;nbsp; The thought right now is to keep a pretty spare core MVC infrastructure in the core assemblies and add additional UI magic in external assemblies that can be optionally added into your project.&amp;nbsp; The Html conventions feature was already developed in this way.&amp;nbsp; In the next 3-4 months I know where adding new facilities for localization, validation, and some more Html conventions on top of those things &amp;ndash; but none of it will come out of the box.&amp;nbsp; The &amp;ldquo;tinker toy&amp;rdquo; approach gives us a huge advantage in being able to adapt FubuMVC for totally new scenarios and reuse code and avoid the original Rails problem of &amp;ldquo;use my opinions or go home,&amp;rdquo; but&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How the bleep is the average team going to be able to assemble all these little pieces and get them to work together without losing all their hair?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt; My personal goal for FubuMVC is to get that question answered &amp;ndash; and I&amp;rsquo;m hoping that Pablo&amp;rsquo;s Fiesta moves the conversation.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=652546" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="FubuMVC" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx" /></entry><entry><title>Preview of the new StoryTeller Test Editor -- Looking for Feedback</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/19/preview-of-the-new-storyteller-test-editor-looking-for-feedback.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/19/preview-of-the-new-storyteller-test-editor-looking-for-feedback.aspx</id><published>2010-02-19T14:35:00Z</published><updated>2010-02-19T14:35:00Z</updated><content type="html">&lt;p&gt;EDIT:&amp;nbsp; 9:40 AM CST -- fixed the download.&amp;nbsp; Missed one absolute path hiding at the bottom of the page.&amp;nbsp; Sorry about that.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In November I made a post about &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2009/11/09/design-conundrum-for-storyteller-opinions-wanted.aspx"&gt;rewriting the StoryTeller test editor&lt;/a&gt; (because the current one is an embarassment) in which I wondered out loud about whether to do the rewrite in Javascript against an HTML DOM or try again in WPF.&amp;nbsp; Opinions were mixed, but I already had a working proof of concept for the Javascript/HTML model from Dovetail&amp;#39;s rules engine so I went in that direction.&amp;nbsp; I did most of it the day after Thanksgiving, but put it aside until just the past week.&amp;nbsp; Here&amp;#39;s &lt;a href="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jeremy.miller/editor.zip"&gt;a zip file with everything&lt;/a&gt; you need to play around with the new test editor.&amp;nbsp; Just unzip it, and open the Editor.htm file.&amp;nbsp; There&amp;#39;s a dropdown box at the top that gives you the ability to open up one of about 2 dozen sample tests I use in testing.&amp;nbsp; Admittedly, I haven&amp;#39;t tried this thing on IE (shame on me), but it&amp;#39;s running like a champ on Firefox 3.6. If you see any wonkiness after switching tests, just reload the page.&lt;/p&gt;
&lt;p&gt;It isn&amp;#39;t finished yet, but it can happily open up StoryTeller tests with every type of grammar and fixture mode and edit them.&amp;nbsp; I still have to apply:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Validation (using jQuery validation)&lt;/li&gt;
&lt;li&gt;Ordering via dragging (again more jQuery goodness)&lt;/li&gt;
&lt;li&gt;&amp;quot;IsDirty&amp;quot; checking&lt;/li&gt;
&lt;li&gt;More styling I&amp;#39;m sure&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;#39;d really like some feedback on both the look and feel plus the usability aspects of the test editor.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My thought is that this test editor will be embedded inside the StoryTeller WPF client as just a screen.&amp;nbsp; It&amp;#39;s also my thought that this could be adapted a little bit down the road as a way to host a StoryTeller DSL editor within a web application.&amp;nbsp; As if I didn&amp;#39;t have enough on my plate already, I&amp;#39;m very serious about pushing StoryTeller as a tool for creating external DSL&amp;#39;s in .Net as well as being the FitNesse killer for .Net.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=640909" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="StoryTeller" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/StoryTeller/default.aspx" /></entry><entry><title>Our “Extension Properties” Story</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/16/our-extension-properties-story.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/16/our-extension-properties-story.aspx</id><published>2010-02-16T14:51:00Z</published><updated>2010-02-16T14:51:00Z</updated><content type="html">&lt;p&gt; Late last year I made myself a promise that I would resuscitate my blog instead of just tweeting drivel.&amp;nbsp; I don&amp;rsquo;t particularly feel up (or self important enough) to the old &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/01/08/Orthogonal-Code.aspx"&gt;10 page missives of yore&lt;/a&gt;, so I&amp;rsquo;m just going to write about the project and OSS work I&amp;rsquo;m doing this year and see if any of it is useful or interesting.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve built software in some capacity for a dozen years.&amp;nbsp; My first couple projects were exciting just because it was my first couple projects, but for the most part, I&amp;rsquo;ve always felt like everybody else worked on cooler projects than I did &amp;ndash; until I started at Dovetail anyway.&amp;nbsp; Yesterday I (mostly) wrapped up a crucial subsystem for us on our story for &amp;ldquo;extension properties that I thought was cool enough to share.&lt;/p&gt;
&lt;p&gt;We know from experience that our customers need to add some of their own fields to track their own special data in the system.&amp;nbsp; Here&amp;rsquo;s the facts, requirements, and assumptions we&amp;rsquo;ve made about these extension properties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We&amp;rsquo;re assuming that the extension properties will be completely set up by our professional services folks during the deployment product, so we don&amp;rsquo;t have to open up any magic way for the customers to change the database schema and screens on the fly.&lt;/li&gt;
&lt;li&gt;Our &amp;ldquo;professional services&amp;rdquo; guys sit 10 feet from me and they&amp;rsquo;re perfectly capable of some coding&lt;/li&gt;
&lt;li&gt;We really need an &amp;ldquo;&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc546578.aspx"&gt;Open / Closed&lt;/a&gt;&amp;rdquo; architecture.&amp;nbsp; By this I mean that we absolutely must be able to add these customer specific properties to their own installation without any impact or change to our core codebase.&amp;nbsp; Nothing destroys a small ISV like having to maintain customer specific &lt;/li&gt;
&lt;li&gt;The extension properties have to be editable on the screen&lt;/li&gt;
&lt;li&gt;The extension properties have to be available inside our rules engine&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;d really, really like to reuse all our existing infrastructure for validation, persistence, and html conventions for these extension properties.&amp;nbsp; I&amp;rsquo;m lazy and I don&amp;rsquo;t want to write a lot of special infrastructure.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Step 1:&amp;nbsp; Adding Extends&amp;lt;T&amp;gt; to the Domain Model&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;My original thought was to just make the extension properties live in a name/value collection on all of our entities.&amp;nbsp; It&amp;rsquo;s a simple solution and the quickie NHibernate spike I did made it clear that the persistence wouldn&amp;rsquo;t be a problem.&amp;nbsp; However, we make use of a *lot* of conventions and validation policies in our application that utilize the type system and our validation attributes to drive behavior.&amp;nbsp; Using the name/value approach meant that I threw all that away.&amp;nbsp; Instead, I decided that the extension properties would just live in a separate class like this one that I use for testing:&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 object would be attached to our &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Site objects in our Domain Model&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;SiteExtensions&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Extends&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Site&lt;/span&gt;&amp;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;Required&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;ShowNew&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; ExtraString { &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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; ExtraNumber { &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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;? ExtraDate { &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:green;"&gt;// Fake property and a fake list I use to 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:green;"&gt;// multi-level lists&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;ListValue&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Year&amp;quot;&lt;/span&gt;), &lt;span style="color:#2b91af;"&gt;ShowNew&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; Year { &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;ListValue&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Make&amp;quot;&lt;/span&gt;), &lt;span style="color:#2b91af;"&gt;ShowNew&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; Make { &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;ListValue&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Model&amp;quot;&lt;/span&gt;), &lt;span style="color:#2b91af;"&gt;ShowNew&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; Model { &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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;A couple notes about this class.&amp;nbsp; As you see, it inherits from the Extends&amp;lt;TEntity&amp;gt; class where TEntity is the type in our domain model that is being extended.&amp;nbsp; Extends&amp;lt;TEntity&amp;gt; is strictly a marker interface with no functionality.&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;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Extends&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style="color:blue;"&gt;where&lt;/span&gt; T : &lt;span style="color:#2b91af;"&gt;DomainEntity&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; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You might also notice that the SiteExtensions class is decorated with several attributes (Required, ShowNew, ListValue, etc.).&amp;nbsp; These attributes are mostly for our server side validation, but they also drive Html construction in the web pages and tie into client side validation with jQuery validation (more on this later).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Step 2:&amp;nbsp; Discovering Extension Properties on Application Startup&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;So far, so good, but now I need to hook the SiteExtensions objects to Site objects while keeping the SiteExtensions class in a totally separate assembly specific to that particular customer.&amp;nbsp; First, all of our domain model classes implement a &lt;a href="http://martinfowler.com/eaaCatalog/layerSupertype.html"&gt;layer supertype&lt;/a&gt; class called &amp;ldquo;DomainEntity,&amp;rdquo; so this becomes a natural way to connect our domain entities to their extension 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:#2b91af;"&gt;Serializable&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;DomainEntity&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Entity&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IValidated&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; &lt;span style="color:blue;"&gt;object&lt;/span&gt; ExtendedProperties { &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; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Next, I need to discover the proper extension property class for each domain model type (if any) at runtime.&amp;nbsp; I decided to store that information in a simple static class called &amp;ldquo;ExtensionProperties&amp;rdquo; that acts as a well known place in the system to query for the proper type of extension class:&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;static&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ExtensionProperties&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;private&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Cache&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;&amp;gt; _types = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Cache&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Type&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;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Register(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; entityType, &lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; extensionType)&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; _types[entityType] = extensionType;&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:blue;"&gt;void&lt;/span&gt; ClearAll()&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; _types.ClearAll();&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:blue;"&gt;bool&lt;/span&gt; HasExtensionFor(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; entityType)&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; _types.Has(entityType);&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;Type&lt;/span&gt; ExtensionFor(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; type)&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; _types[type];&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&amp;rsquo;ve got ExtensionProperties, we need to discover the available extension properties at application startup and register them with ExtensionProperties.&amp;nbsp; Unsurprisingly, I used StructureMap to discover the extension property types.&amp;nbsp; First off, we&amp;rsquo;re doing customer extensions by placing their customizations in separate assemblies that are placed into our application bin.&amp;nbsp; At the moment, our convention is that these assemblies must contain &amp;ldquo;Extensions&amp;rdquo; somewhere in their assembly name to be picked up.&amp;nbsp; So knowing that assumption, I created an auto-registration policy in StructureMap that scans all the &amp;ldquo;Extensions&amp;rdquo; assemblies in our application base directory and discovers the Extends&amp;lt;T&amp;gt; types:&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;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ExtensionRegistry&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Registry&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; ExtensionRegistry()&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; Scan(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:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.ClearAll();&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.AssembliesFromApplicationBaseDirectory(assem =&amp;gt; assem.GetName().Name.Contains(&lt;span style="color:#a31515;"&gt;&amp;quot;Extensions&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; x.Convention&amp;lt;&lt;span style="color:#2b91af;"&gt;ExtensionScanner&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; });&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;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:green;"&gt;// This little guy just finds any type that inherits from&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Extends&amp;lt;T&amp;gt; and registers that type against &amp;quot;T&amp;quot; in &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// our wellknown ExtensionProperties class&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;ExtensionScanner&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;IRegistrationConvention&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; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Process(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; type, &lt;span style="color:#2b91af;"&gt;Registry&lt;/span&gt; graph)&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;if&lt;/span&gt; (type.BaseType.IsGenericType &amp;amp;&amp;amp; type.BaseType.GetGenericTypeDefinition() == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Extends&lt;/span&gt;&amp;lt;&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;var&lt;/span&gt; entityType = type.BaseType.GetGenericArguments()[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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.Register(entityType, type);&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;h4&gt;&lt;b&gt;Step 3:&amp;nbsp; Persisting the little devils&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;The goal is definitely to make the properties on the extension classes persistent, and I&amp;rsquo;d really prefer not to write custom SQL for this one off need, so it&amp;rsquo;s time to teach NHibernate how to persist these extension types &amp;ndash; if they exist.&amp;nbsp; The Extends&amp;lt;T&amp;gt; objects are really just part of the domain entity that they extend, so let&amp;rsquo;s just say we put the backing fields directly onto the proper table for each entity.&amp;nbsp; We *might* have a conflict with the extension properties and later versions of our product, so let&amp;rsquo;s make a little naming convention for these backing fields and say that all extension fields in the database have to be prepended with &amp;ldquo;x_&amp;rdquo; like this (yes kids, I *can* write Sql by hand if I absolutely have to):&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;&lt;span style="color:blue;"&gt;BEGIN TRANSACTION&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;GO&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;ALTER TABLE &lt;/span&gt;dbo.Site &lt;span style="color:blue;"&gt;ADD&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x_ExtraString nvarchar(50) &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; x_ExtraNumber &lt;span style="color:blue;"&gt;int NULL&lt;/span&gt;,&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x_ExtraDate &lt;span style="color:blue;"&gt;datetime 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; x_Year nvarchar(20) &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; x_Make nvarchar(50) &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; x_Model nvarchar(100) &lt;span style="color:blue;"&gt;NULL&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;COMMIT&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now I need to alter our NHibernate mappings *if* a domain entity has an extension type attached to it.&amp;nbsp; Back in the bad old HBM.XML days this used to be a klooge, but Fluent NHibernate (FNH) made it very simple.&amp;nbsp; Let&amp;rsquo;s just treat the Extends&amp;lt;T&amp;gt; type as a &amp;ldquo;&lt;a href="https://www.hibernate.org/hib_docs/nhibernate/html/components.html"&gt;Component&lt;/a&gt;&amp;rdquo; on the main entity type.&amp;nbsp; We have our own base class that extends FNH&amp;rsquo;s ClassMap&amp;lt;T&amp;gt; called DomainMap&amp;lt;T&amp;gt; to specify NHibernate mappings with our own policies, so let&amp;rsquo;s just add a bit of code to that base class that will dynamically create a component mapping to the extension property type if it exists:&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;abstract&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;DomainMap&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;ClassMap&lt;/span&gt;&amp;lt;T&amp;gt;, &lt;span style="color:#2b91af;"&gt;IDomainMap&lt;/span&gt; &lt;span style="color:blue;"&gt;where&lt;/span&gt; T : &lt;span style="color:#2b91af;"&gt;DomainEntity&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; DomainMap()&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:green;"&gt;// For every DomainEntity class, use the Id 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// as the Primary Key / Object Identifier&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; Id(x =&amp;gt; x.Id).ColumnName(&lt;span style="color:#a31515;"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;).GeneratedBy.GuidComb();&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; WithTable(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(T).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; Map(x =&amp;gt; x.LastModified);&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; Map(x =&amp;gt; x.Created);&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; (&lt;span style="color:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.HasExtensionFor(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(T)))&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;var&lt;/span&gt; componentType = &lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;ExtensionComponent&lt;/span&gt;&amp;lt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .MakeGenericType(&lt;span style="color:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.ExtensionFor(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (T)));&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; component = &lt;span style="color:#2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance(componentType) &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IMappingPart&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; AddPart(component);&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;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; &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;ExtensionComponent&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;ComponentPart&lt;/span&gt;&amp;lt;T&amp;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; ExtensionComponent()&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;base&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ReflectionHelper&lt;/span&gt;.GetProperty&amp;lt;&lt;span style="color:#2b91af;"&gt;DomainEntity&lt;/span&gt;&amp;gt;(x =&amp;gt; x.ExtendedProperties), &lt;span style="color:blue;"&gt;false&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetAttribute(&lt;span style="color:#a31515;"&gt;&amp;quot;class&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(T).AssemblyQualifiedName);&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;// Assume that all properties are persistable&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:blue;"&gt;typeof&lt;/span&gt;(T).GetProperties()&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; .Where(x =&amp;gt; x.DeclaringType == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(T))&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; .Each(prop =&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:green;"&gt;// See the &amp;quot;x_&amp;quot; prefix for the naming convention?&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; Map(prop, &lt;span style="color:#a31515;"&gt;&amp;quot;x_&amp;quot;&lt;/span&gt; + prop.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; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The awesome thing about using an &amp;ldquo;&lt;a href="http://www.martinfowler.com/bliki/DomainSpecificLanguage.html"&gt;internal DSL&lt;/a&gt;&amp;rdquo; like that in Fluent NHibernate is that you still have every single bit of the real language at your disposal.&amp;nbsp; The code above effectively extends our NHibernate mapping to persist all the properties of the Extends&amp;lt;T&amp;gt; objects whenever the host entity is persisted.&amp;nbsp; By doing this we largely make the extension property persistence transparent to the main code.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Step 3:&amp;nbsp; Validating the Extension Properties&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;This part is actually pretty simple, but it doesn&amp;rsquo;t really translate all that well to other codebases.&amp;nbsp; For validation we use a homegrown mini-framework I built years ago that lives (largely abandoned) in the &lt;a href="http://code.google.com/p/shadetree/"&gt;ShadeTree&lt;/a&gt; repository on Google Code (it hasn&amp;rsquo;t changed a lot since &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx"&gt;this post on the Notification pattern&lt;/a&gt;).&amp;nbsp; This tooling allows you to mix validation between attributes and special methods on a Domain Entity.&amp;nbsp; Going back to our DomainEntity supertype, we make it implement the ShadeTree &amp;ldquo;IValidated&amp;rdquo; interface and in the single Validate(Notification) method, we do a transparent pass through to validate the extension 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:#2b91af;"&gt;Serializable&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;DomainEntity&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Entity&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IValidated&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;&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;virtual&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Validate(&lt;span style="color:#2b91af;"&gt;Notification&lt;/span&gt; notification)&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;if&lt;/span&gt; (ExtendedProperties == &lt;span style="color:blue;"&gt;null&lt;/span&gt;) &lt;span style="color:blue;"&gt;return&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Validator&lt;/span&gt;.ValidateObject(ExtendedProperties, notification);&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;object&lt;/span&gt; ExtendedProperties { &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; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Not really much to this.&amp;nbsp; Your mechanics will be different for other validation frameworks, but the principle is still the same.&amp;nbsp; Just validate the extension property object if it exists and add those messages to whatever your framework uses for its Notification.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Step 4:&amp;nbsp; Putting this stuff on the screen&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Most of our online forms present the main fields in a pretty standard 2 column layout.&amp;nbsp; For the moment, we&amp;rsquo;re trying to get away with just adding any extension properties to the bottom of the two columns and hope that&amp;rsquo;s good enough for most clients.&amp;nbsp; Once Chad and I made that assumption I moved onto making a new Html helper that would dynamically add the labels and editable fields for any extension 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="background:#ffee62;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;=this&lt;/span&gt;.ExtensionFieldsForView()&lt;span style="background:#ffee62;"&gt;%&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This helper needs to discover the proper extension type, if any, and write a label/field pair for each property it discovers on that extension object:&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;// Discover what extension type, if any, is valid for the ViewModel of this page&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;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; ExtensionFieldsForView&amp;lt;TViewModel&amp;gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IDovetailViewWithModel&lt;/span&gt;&amp;lt;TViewModel&amp;gt; view) &lt;span style="color:blue;"&gt;where&lt;/span&gt; TViewModel : &lt;span style="color:blue;"&gt;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; {&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;var&lt;/span&gt; form = buildFormFor(view);&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;var&lt;/span&gt; entityModel = view.Model &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EditEntityModel&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:blue;"&gt;return&lt;/span&gt; form == &lt;span style="color:blue;"&gt;null&lt;/span&gt; ? &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt;.Empty() : form.WriteView(entityModel.Target);&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;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IExtensionForm&lt;/span&gt; buildFormFor&amp;lt;TViewModel&amp;gt;(&lt;span style="color:#2b91af;"&gt;IDovetailViewWithModel&lt;/span&gt;&amp;lt;TViewModel&amp;gt; view) &lt;span style="color:blue;"&gt;where&lt;/span&gt; TViewModel : &lt;span style="color:blue;"&gt;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; {&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;var&lt;/span&gt; editModel = view.Model &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EditEntityModel&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:blue;"&gt;if&lt;/span&gt; (editModel == &lt;span style="color:blue;"&gt;null&lt;/span&gt;) &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;null&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; entityType = editModel.EntityType;&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; (!&lt;span style="color:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.HasExtensionFor(entityType)) &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;null&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;&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;// The Form &amp;quot;magic&amp;quot; happens in ExtensionForm&amp;lt;,&amp;gt;&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:blue;"&gt;var&lt;/span&gt; extensionType = &lt;span style="color:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.ExtensionFor(entityType);&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;var&lt;/span&gt; extenderFormType = &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ExtensionForm&lt;/span&gt;&amp;lt;,&amp;gt;).MakeGenericType(extensionType, 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;IExtensionForm&lt;/span&gt;)view.Container.GetInstance(extenderFormType);&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;One of my goals with the extension properties was to utilize our existing infrastructure for Html generation.&amp;nbsp; We have a large investment in the &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2010/01/29/shrink-your-views-with-fubumvc-html-conventions.aspx"&gt;FubuMVC Html conventions&lt;/a&gt; and it makes our form creation quick and consistent.&amp;nbsp; In order to use the Html conventions with our extension properties, I use this utility class to mediate between the dynamically discovered extension properties and the Fubu Html conventions:&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;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IExtensionForm&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;HtmlTag&lt;/span&gt; WriteNew();&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;HtmlTag&lt;/span&gt; WriteView(&lt;span style="color:#2b91af;"&gt;DomainEntity&lt;/span&gt; entity);&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;&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;ExtensionForm&lt;/span&gt;&amp;lt;T, TEntity&amp;gt; : &lt;span style="color:#2b91af;"&gt;IExtensionForm&lt;/span&gt; &lt;span style="color:blue;"&gt;where&lt;/span&gt; T : &lt;span style="color:#2b91af;"&gt;Extends&lt;/span&gt;&amp;lt;TEntity&amp;gt;, &lt;span style="color:blue;"&gt;new&lt;/span&gt;() &lt;span style="color:blue;"&gt;where&lt;/span&gt; TEntity : &lt;span style="color:#2b91af;"&gt;DomainEntity&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;private&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TagGenerator&lt;/span&gt;&amp;lt;T&amp;gt; _tags;&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; ExtensionForm(&lt;span style="color:#2b91af;"&gt;TagGenerator&lt;/span&gt;&amp;lt;T&amp;gt; tags)&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; _tags = tags;&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;// This is consistent w/ our naming convention&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; _tags.ElementPrefix = &lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (TEntity).Name;&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:#2b91af;"&gt;HtmlTag&lt;/span&gt; writeFields(&lt;span style="color:blue;"&gt;string&lt;/span&gt; profileName, &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt; properties)&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; _tags.SetProfile(profileName);&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;dl&amp;quot;&lt;/span&gt;, 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.AddClass(&lt;span style="color:#a31515;"&gt;&amp;quot;details&amp;quot;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; properties.Each(prop =&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; x.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;dt&amp;quot;&lt;/span&gt;).Text(&lt;span style="color:#2b91af;"&gt;LocalizationManager&lt;/span&gt;.GetHeader(prop));&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; request = _tags.GetRequest(&lt;span style="color:blue;"&gt;new&lt;/span&gt; FubuMVC.Core.Util.&lt;span style="color:#2b91af;"&gt;SingleProperty&lt;/span&gt;(prop));&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;HtmlTag&lt;/span&gt; inputTag = _tags.InputFor(request);&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.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;dd&amp;quot;&lt;/span&gt;).Child(inputTag);&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:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HtmlTag&lt;/span&gt; WriteNew()&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; _tags.Model = &lt;span style="color:blue;"&gt;new&lt;/span&gt; T();&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; writeFields(&lt;span style="color:#2b91af;"&gt;TagProfile&lt;/span&gt;.DEFAULT, &lt;span style="color:#2b91af;"&gt;ExtensionFieldRegistry&lt;/span&gt;.NewProperties&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;/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:#2b91af;"&gt;HtmlTag&lt;/span&gt; WriteView(&lt;span style="color:#2b91af;"&gt;DomainEntity&lt;/span&gt; entity)&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; _tags.Model = (T) entity.ExtendedProperties ?? &lt;span style="color:blue;"&gt;new&lt;/span&gt; T();&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; writeFields(&lt;span style="color:#2b91af;"&gt;DovetailViewActivator&lt;/span&gt;.EDIT_PROFILE, &lt;span style="color:#2b91af;"&gt;ExtensionFieldRegistry&lt;/span&gt;.ViewProperties&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;/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;TagGenerator&amp;lt;T&amp;gt; is the main service in FubuMVC.UI for generating HtmlTag&amp;rsquo;s by convention.&amp;nbsp; As you can probably surmise from the code above, our localization machinery can lookup the header name for a PropertyInfo (or Expression) and that&amp;rsquo;s how we build the labels.&amp;nbsp; The actual editor tag is completely generated by the FubuMVC machinery based on its policies that we&amp;rsquo;ve configured:&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;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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dates();&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.Builder&amp;lt;&lt;span style="color:#2b91af;"&gt;ListValueDropdownBuilder&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.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;())&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; .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;)&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; .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;&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; 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:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; dates()&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.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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Editors.If(prop =&amp;gt; prop.Accessor.InnerProperty.IsDateAndTime()).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;time-picker&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: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;And of course, by using the normal Html conventions to build the Html input tags, we get the jQuery validation integration for our extension properties.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Oh, and because Reflection scanning can be expensive, we cache the PropertyInfo&amp;rsquo;s for each extension type:&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;static&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ExtensionFieldRegistry&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;private&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Cache&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt;&amp;gt; _newProps&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;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Cache&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;,&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt;&amp;gt;(findNewProps);&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;static&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Cache&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt;&amp;gt; _viewProps&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;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Cache&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;,&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt;&amp;gt;(findViewProps);&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;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt; findNewProps(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; type)&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; type.GetProperties().Where(x =&amp;gt; x.DeclaringType == type &amp;amp;&amp;amp; x.HasAttribute&amp;lt;&lt;span style="color:#2b91af;"&gt;ShowNewAttribute&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;private&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt; findViewProps(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; type)&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; type.GetProperties().Where(x =&amp;gt; x.DeclaringType == type);&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;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt; NewProperties&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;/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; _newProps[&lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (T)];&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;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;&amp;gt; ViewProperties&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;/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; _viewProps[&lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (T)];&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;Step 5:&amp;nbsp; Getting data from the browser to the server&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;One more step (we also do edit in place editing of the extension properties in the UI, but that code is a mess and I&amp;rsquo;m not showing it to anyone until it&amp;rsquo;s cleaner).&amp;nbsp; We have the html tags on the browser and NHibernate knows how to persist the fields.&amp;nbsp; All we have to do now is get the data from the browser and marshal it into the new extension property type on the server.&amp;nbsp; The ViewModels for submitting the &amp;ldquo;new&amp;rdquo; forms all inherit from this base type that, conveniently enough, has a property for the extension 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;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;UpdateEntityModel&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;IItemRequest&lt;/span&gt; &lt;span style="color:blue;"&gt;where&lt;/span&gt; T : &lt;span style="color:#2b91af;"&gt;DomainEntity&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; &lt;span style="color:#2b91af;"&gt;Extends&lt;/span&gt;&amp;lt;T&amp;gt; ExtendedProperties { &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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt; Id{ &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;I&amp;rsquo;m omitting some (lots) of code here, but I used an extension point on FubuMVC&amp;rsquo;s model binding to &amp;ldquo;fill&amp;rdquo; that ExtendedProperties property above with this code:&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;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ExtensionPropertyBinder&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;IPropertyBinder&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;// This only applies to properties that close Extends&amp;lt;&amp;gt;&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;bool&lt;/span&gt; Matches(&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt; property)&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; property.PropertyType.Closes(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Extends&lt;/span&gt;&amp;lt;&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;void&lt;/span&gt; Bind(&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt; property, &lt;span style="color:#2b91af;"&gt;IBindingContext&lt;/span&gt; context)&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;var&lt;/span&gt; entityType = property.PropertyType.GetGenericArguments()[0];&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;// If there is no Extends&amp;lt;&amp;gt; for the entity type, do nothing&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:blue;"&gt;if&lt;/span&gt; (!&lt;span style="color:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.HasExtensionFor(entityType))&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;return&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; &lt;span style="color:blue;"&gt;var&lt;/span&gt; extensionType = &lt;span style="color:#2b91af;"&gt;ExtensionProperties&lt;/span&gt;.ExtensionFor(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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// direct the FubuMVC model binding to resolve an object of the&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;// extensionType using &amp;quot;entityType.Name&amp;quot; as the prefix on the form data,&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;// and place the newly created object using the specified 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.BindChild(property, extensionType, entityType.Name);&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;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Wrapping Up&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;We&amp;rsquo;ll see how it goes in the end, but I&amp;rsquo;m relatively happy with how it all turned out.&amp;nbsp; The end result is that we can just build a very simple class with properties and some attribute declarations, put that assembly in the right spot, and voila!, the right stuff appears on the screen.&lt;/p&gt;
&lt;p&gt;Lots of stuff to throw at you, but I&amp;rsquo;ll try to answer any questions.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=635366" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="StructureMap" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/StructureMap/default.aspx" /><category term="FubuMVC" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx" /></entry><entry><title>Wanna see how Dovetail builds software (or not, it's a free country)?</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/12/wanna-see-how-dovetail-builds-software-or-not-it-s-a-free-country.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/12/wanna-see-how-dovetail-builds-software-or-not-it-s-a-free-country.aspx</id><published>2010-02-13T03:41:00Z</published><updated>2010-02-13T03:41:00Z</updated><content type="html">&lt;p&gt;Chad Myers and I are more or less volunteering to put on a 4 hour session at the &lt;a href="http://austin-codecamp-2010.eventbrite.com/"&gt;2010 Austin Code Camp&lt;/a&gt; (for a variety of reasons this is the first time I&amp;#39;ve been to it since &amp;#39;06) just presenting an insider&amp;#39;s look at some of the project work we&amp;#39;re doing in the spirit of our &amp;quot;&lt;a href="http://www.viddler.com/explore/lostechies/videos/2/"&gt;Opinionated MVC&lt;/a&gt;&amp;quot; talk from KaizenConf in &amp;#39;08.&amp;nbsp; We can talk about almost anything but actual business logic, but here&amp;#39;s the topics I&amp;#39;m thinking of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dovetail&amp;#39;s &amp;quot;rules engine.&amp;quot;&amp;nbsp; We have a custom rules engine built on the standard Event - Condition - Action pattern that works against our domain model.&amp;nbsp; The E-C-A parts are all composed with StructureMap and the rules configuration is done by an external DSL editor that presents a near English experience for users.&amp;nbsp; It&amp;#39;s also very extensible for those pesky customer customizations down the road.&amp;nbsp; I think this is the most challenging project I&amp;#39;ve ever done by far.&amp;nbsp; Oh, and we can add new &amp;quot;Condition&amp;#39;s&amp;quot; and &amp;quot;Action&amp;#39;s&amp;quot; to both the engine and DSL without changing one single line in our core Dovetail code.&amp;nbsp; How &amp;#39;bout them apples?&lt;/li&gt;
&lt;li&gt;How we use StoryTeller and Selenium to do automated web testing.&amp;nbsp; Lots of challenges and lessons learned to make testing go faster and be less brittle in an Ajax heavy site.&lt;/li&gt;
&lt;li&gt;Using FubuMVC.&amp;nbsp; How it really plays out.&amp;nbsp; Using the Html conventions to really go fast and kill repetitive coding -- and it goes way beyond what anything in MSMVC2 is capable of w/o heavy gymnastics.&amp;nbsp; Advanced model binding.&amp;nbsp; How we get eliminate the &amp;quot;tag soup&amp;quot; problem in our views.&lt;/li&gt;
&lt;li&gt;Tying jQuery together with server side conventions and Html helpers.&amp;nbsp; A lot of the pizzazz of jQuery is only unleashed when you combine it with your server side Html generation.&lt;/li&gt;
&lt;li&gt;Our &amp;quot;ActionRouter&amp;quot; / Continuation model for some Ajax handling.&amp;nbsp; It&amp;#39;s a cool little sample of making an internal DSL pay off dividends&lt;/li&gt;
&lt;li&gt;Convention over Configuration from our Domain Model back to the database and forward to the UI&lt;/li&gt;
&lt;li&gt;Extension properties.&amp;nbsp; We have a need in our application to allow customers (or really our professional services folks) to add new properties to our system and capture this data on the screen with fullblown validation and edit in place functionality without touching our core code.&amp;nbsp; Lots of Fluent NHibernate and FubuMVC trickery to make it work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Anything you want to hear about?&amp;nbsp; We&amp;#39;ll get it filmed and posted on Viddler or something similar.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=631146" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author></entry><entry><title>Introducing the "Ignite Your Coding!" Podcast</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/10/introducing-the-quot-ignite-your-coding-quot-podcast.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/10/introducing-the-quot-ignite-your-coding-quot-podcast.aspx</id><published>2010-02-10T21:36:00Z</published><updated>2010-02-10T21:36:00Z</updated><content type="html">&lt;p&gt;I enjoy the better software podcasts out there, but there aren&amp;#39;t really enough good ones out there and some of them would really be better if they contained a little more element of conversation and even debate once in awhile instead of being just a straight forward presentation from the guest.&amp;nbsp; I&amp;#39;m really looking forward to see what those crazy Canucks get up to with the new &lt;a href="http://msdn.microsoft.com/en-ca/ff182908.aspx"&gt;Ignite Your Coding podcast&lt;/a&gt; starting up soon.&amp;nbsp; The guest list and schedule looks pretty good, but the most intriguing thing to me is the interactive nature of the webcast format where listeners can ask questions live.&amp;nbsp; The very first episode is going to be Andy Hunt of Pragmatic Programmer fame with Uncle Bob and several CodeBetter members in between.&lt;/p&gt;
&lt;p&gt;You can find more information from &lt;a href="http://www.globalnerdy.com/2010/02/10/the-ignite-your-coding-podcast-series/"&gt;Joey Devilla&amp;#39;s blog post&lt;/a&gt; kicking it off.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;#39;ll be on it March 18th.&amp;nbsp; If you absolutely feel like you need to write what you&amp;#39;d like me to discuss in the comments below, I guess that&amp;#39;d be (very helpful) okay.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=629385" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author></entry><entry><title>“Nested Containers” in StructureMap 2.6.1</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/10/nested-containers-in-structuremap-2-6-1.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/10/nested-containers-in-structuremap-2-6-1.aspx</id><published>2010-02-10T05:36:00Z</published><updated>2010-02-10T05:36:00Z</updated><content type="html">&lt;p&gt;This is the first of a promised series of blog posts to explain and demonstrate the new features of the &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2010/02/04/structuremap-2-6-and-2-5-4-is-released.aspx"&gt;StructureMap 2.6 release&lt;/a&gt;.&amp;nbsp; First, in order to use this feature, you absolutely must be on StructureMap 2.6.1 (or 2.5.4).&amp;nbsp; Your friendly neighborhood Shade Tree Developer introduced a bug into the 2.6.0 codebase that makes this feature screw up the parent container (mea culpa).&lt;/p&gt;
&lt;p&gt;I want to start with the new &amp;ldquo;Nested Container&amp;rdquo; feature.&amp;nbsp; In a nutshell, the Nested Container is kind of like a temporary clone of a Container that&amp;rsquo;s invoked 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;// Let&amp;#39;s just say that ObjectFactory.Initialize() has already been&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;// called so the main Container is already built and ready&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;// to use&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:blue;"&gt;using&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;IContainer&lt;/span&gt; nested = &lt;span style="color:#2b91af;"&gt;ObjectFactory&lt;/span&gt;.Container.GetNestedContainer())&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:green;"&gt;// pull other objects from the nested&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;span style="color:green;"&gt;// container and do work with those services&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;span style="color:blue;"&gt;var&lt;/span&gt; service = nested.GetInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;IService&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.DoSomething();&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;/div&gt;
&lt;p&gt;What did I do up above?&amp;nbsp; I simply created a new Container (nested) from an existing Container, then pulled a service from the new nested container, did some work with it, then let the C# &amp;ldquo;using&amp;rdquo; block auto magically call the Dispose() method on the new nested container object.&amp;nbsp; You might be asking, why do I need a second Container?&amp;nbsp; Well, the nested container has some special properties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The nested container will track all of the transient objects that it creates.&amp;nbsp; When the nested container itself is disposed, it will call Dispose() on any of the transient objects that it created.&amp;nbsp; A normal StructureMap Container does not track the transient objects that it creates (and nor should it IMHO).&lt;/li&gt;
&lt;li&gt;The nested container &amp;ldquo;pulls&amp;rdquo; all instances scoped as anything but transients (Singletons, HttpContext scoped objects, ThreadLocalStorage scoped objects, etc.) from the parent container.&amp;nbsp; These objects are not disposed from the nested container.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&amp;ldquo;Transient&amp;rdquo; objects are scoped to the nested container&lt;/b&gt;.&amp;nbsp; I&amp;rsquo;d try to explain that, but why don&amp;rsquo;t I just show the unit test instead:&lt;/li&gt;
&lt;/ol&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; transient_service_in_the_parent_container_is_effectively_a_singleton_for_the_nested_container()&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;var&lt;/span&gt; parent = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Container&lt;/span&gt;(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:green;"&gt;// IWidget is a &amp;quot;transient&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; x.For&amp;lt;&lt;span style="color:#2b91af;"&gt;IWidget&lt;/span&gt;&amp;gt;().Use&amp;lt;&lt;span style="color:#2b91af;"&gt;AWidget&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; });&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:#2b91af;"&gt;IContainer&lt;/span&gt; child = parent.GetNestedContainer();&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;var&lt;/span&gt; childWidget1 = child.GetInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;IWidget&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; &lt;span style="color:blue;"&gt;var&lt;/span&gt; childWidget2 = child.GetInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;IWidget&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; &lt;span style="color:blue;"&gt;var&lt;/span&gt; childWidget3 = child.GetInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;IWidget&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;var&lt;/span&gt; parentWidget = parent.GetInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;IWidget&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; childWidget1.ShouldBeTheSameAs(childWidget2);&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; childWidget1.ShouldBeTheSameAs(childWidget3);&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; childWidget1.ShouldNotBeTheSameAs(parentWidget);&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt; It&amp;rsquo;s not the most exciting thing in the world, but it&amp;rsquo;s helpful in some specific scenarios:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Web requests.&amp;nbsp; Inside a single web request I need every object to access the exact same NHibernate ISession instance (substitute the analogue in your persistence tooling of choice).&amp;nbsp; At the end of the web request I may want to tear down and dispose all the services created during that web request &amp;ndash; i.e. make damn sure the database connection is closed and cleaned up at the end.&amp;nbsp; I&amp;rsquo;m not exactly sure how you would use this in ASP.Net MVC (not saying you can&amp;rsquo;t, just that I haven&amp;rsquo;t given it much thought), but it&amp;rsquo;s working out very well for us with a FubuMVC Behavior like &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2010/01/06/how-dovetail-uses-structuremap-with-nhibernate.aspx"&gt;I showed here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Short lived atomic transactions.&amp;nbsp; We use the nested container within our rules engine.&amp;nbsp; Within a single NHibernate ISession and transaction block, we create several object graphs with service location calls to the nested container.*&amp;nbsp; Using the nested container feature made it much simpler for us to &amp;ldquo;scope&amp;rdquo; the ISession and even rules state objects within a logical transaction.&lt;/li&gt;
&lt;li&gt;User Interface composition.&amp;nbsp; From a twitter conversation with &lt;a href="http://codebetter.com/blogs/glenn.block/Default.aspx"&gt;Glenn Block&lt;/a&gt; a couple weeks back.&amp;nbsp; Let&amp;rsquo;s say that you have a distinct area of the UI where you have a long running workflow like a wizard that replaces the controls and Presenters / ViewModels currently active.&amp;nbsp; When those Views, ViewModel&amp;rsquo;s, and Presenters are created, you probably want those objects to have shared state and layout &amp;ldquo;region manager&amp;rdquo; type classes injected into them.&amp;nbsp; Using a nested container for the wizard is &amp;ldquo;a&amp;rdquo; way to build those objects with the proper shared services.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Sample Usage&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Most of our nested container usage is wrapped up within the class shown below:&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;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TransactionProcessor&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;ITransactionProcessor&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;private&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:blue;"&gt;object&lt;/span&gt; _locker = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:blue;"&gt;object&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:#2b91af;"&gt;IContainer&lt;/span&gt; _container;&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;// This IContainer is the parent container from&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;// ObjectFactory.Container&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; TransactionProcessor(&lt;span style="color:#2b91af;"&gt;IContainer&lt;/span&gt; container)&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; _container = container;&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;void&lt;/span&gt; Execute&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; action)&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; execute(c =&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;var&lt;/span&gt; service = c.GetInstance&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; action(service);&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;&lt;span style="color:blue;"&gt;&lt;/span&gt;&lt;/p&gt;
&amp;nbsp;
&lt;p&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;// This code is used in our codebase as a generic way to invoke&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;// a service or action within the scope of a nested container&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; execute(&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IContainer&lt;/span&gt;&amp;gt; action)&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;IContainer&lt;/span&gt; container = &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; &lt;span style="color:blue;"&gt;lock&lt;/span&gt; (_locker)&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; container = _container;&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;// ITransactionBoundary is a Dovetail specific interface / 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:green;"&gt;// we use just to manage an NHibernate ISession object&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:blue;"&gt;using&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;IContainer&lt;/span&gt; nestedContainer = container.GetNestedContainer())&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;var&lt;/span&gt; boundary = nestedContainer.GetInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;ITransactionBoundary&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boundary.Start();&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; action(nestedContainer);&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; boundary.Commit();&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;In real usage, we invoke services within a transaction with code 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; transaction = &lt;span style="color:#2b91af;"&gt;ObjectFactory&lt;/span&gt;.GetInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;ITransactionProcessor&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; transaction.Execute&amp;lt;&lt;span style="color:#2b91af;"&gt;DataDriver&lt;/span&gt;&amp;gt;(x =&amp;gt; x.ClearData());&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;* Some of you are going to read that sentence and do a kneejerk &amp;ldquo;&amp;hellip;but Ayende says you&amp;rsquo;re only supposed to do one service locator call in the entire application!&amp;rdquo;&amp;nbsp; Don&amp;rsquo;t do the kneejerk thing without understanding the context. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=629299" width="1" height="1"&gt;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="StructureMap" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/StructureMap/default.aspx" /></entry><entry><title>More signs of FubuMVC getting real</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/09/more-signs-of-fubumvc-getting-real.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/09/more-signs-of-fubumvc-getting-real.aspx</id><published>2010-02-09T14:52:00Z</published><updated>2010-02-09T14:52:00Z</updated><content type="html">&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;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="FubuMVC" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx" /></entry><entry><title>StructureMap 2.6 (and 2.5.4) is Released!</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/04/structuremap-2-6-and-2-5-4-is-released.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/04/structuremap-2-6-and-2-5-4-is-released.aspx</id><published>2010-02-04T15:14:00Z</published><updated>2010-02-04T15:14:00Z</updated><content type="html">&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;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="StructureMap" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/StructureMap/default.aspx" /></entry><entry><title>Getting StructureMap off SourceForge, Thoughts?</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/03/getting-structuremap-off-sourceforge-thoughts.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/03/getting-structuremap-off-sourceforge-thoughts.aspx</id><published>2010-02-03T22:29:00Z</published><updated>2010-02-03T22:29:00Z</updated><content type="html">&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;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="StructureMap" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/StructureMap/default.aspx" /></entry><entry><title>FubuMVC Learns to Speak Spark</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/02/02/fubumvc-learns-to-speak-spark.aspx" /><id>/blogs/jeremy.miller/archive/2010/02/02/fubumvc-learns-to-speak-spark.aspx</id><published>2010-02-02T17:59:00Z</published><updated>2010-02-02T17:59:00Z</updated><content type="html">&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;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author><category term="FubuMVC" scheme="http://codebetter.com/blogs/jeremy.miller/archive/tags/FubuMVC/default.aspx" /></entry><entry><title>Dovetail is Hiring</title><link rel="alternate" type="text/html" href="/blogs/jeremy.miller/archive/2010/01/29/dovetail-is-hiring.aspx" /><id>/blogs/jeremy.miller/archive/2010/01/29/dovetail-is-hiring.aspx</id><published>2010-01-29T21:17:00Z</published><updated>2010-01-29T21:17:00Z</updated><content type="html">&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;</content><author><name>jmiller</name><uri>http://codebetter.com/members/jmiller/default.aspx</uri></author></entry></feed>