<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Devlicio.us - Just the Tasty Bits</title><link>http://devlicio.us/blogs/</link><description>Your Agile .NET Community</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Devlicious" /><feedburner:info uri="devlicious" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>“Build Your Own MVVM Framework” is Online</title><link>http://feedproxy.google.com/~r/Devlicious/~3/vj1H86p1Ayg/build-your-own-mvvm-framework-is-online.aspx</link><pubDate>Tue, 16 Mar 2010 22:37:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56116</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Yesterday I delivered my talk, &lt;a href="http://live.visitmix.com/MIX10/Sessions/EX15"&gt;&amp;ldquo;Build Your Own MVVM Framework,&amp;rdquo;&lt;/a&gt; at Mix.&amp;nbsp; Thanks to all who came out to listen and allow me a short time to share some of my ideas.&amp;nbsp; I&amp;rsquo;m very grateful to have had this opportunity.&amp;nbsp; Thanks also to all who voted for the talk.&amp;nbsp; If you were not able to make it in person, Microsoft has made the video of the session available online along with the slides.&amp;nbsp; You can now watch it at &lt;a href="http://live.visitmix.com/MIX10/Sessions/EX15"&gt;http://live.visitmix.com/MIX10/Sessions/EX15&lt;/a&gt;. I&amp;rsquo;m also providing the full source code for the sample application as an attachment to this blog post.&amp;nbsp; If you look at the source code, there are a few things to keep in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The backend is fake.&lt;/li&gt;
&lt;li&gt;The framework is not intended to be used &amp;ldquo;as is.&amp;rdquo; It was built for this &lt;em&gt;specific &lt;/em&gt;application. You should adapt it to your application, or use &lt;a href="http://caliburnproject.org/"&gt;Caliburn&lt;/a&gt;, which &lt;em&gt;was&lt;/em&gt; designed for general use.&lt;/li&gt;
&lt;li&gt;There are a number of other interesting things in the sample, which I did not discuss in the talk. It&amp;rsquo;s worth poking around a little bit&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope this talk and sample give you some ideas. I would love to hear your feedback.&amp;nbsp; Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56116" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/vj1H86p1Ayg" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MEF/default.aspx">MEF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><feedburner:origLink>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/16/build-your-own-mvvm-framework-is-online.aspx</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/Devlicious/~5/F3ojKqaprd4/Build-Your-Own-MVVM-Framework.zip" length="149731" type="application/x-zip-compressed" /><feedburner:origEnclosureLink>http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.05.61.16/Build-Your-Own-MVVM-Framework.zip</feedburner:origEnclosureLink></item><item><title>Are You Playing Checker or Chess? - YAGNI Revisited</title><link>http://feedproxy.google.com/~r/Devlicious/~3/kbVzf_O85Ec/are-you-playing-checker-or-chess-yagni-revisited.aspx</link><pubDate>Mon, 15 Mar 2010 05:08:37 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55956</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image_5F00_7E5F94FB.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="image" border="0" alt="image" align="right" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image_5F00_thumb_5F00_69954E8E.png" width="377" height="252" /&gt;&lt;/a&gt; This past Saturday I had an early morning coffee with a friend. He’s an entrepreneurial type – a big thinker who moves at a fast pace and is always thinking ahead.&amp;#160; One question he asked of me, “Are you playing checkers or chess?”.&lt;/p&gt;  &lt;p&gt;The question was asked around business and career but I could not help but think of the implications to software.&lt;/p&gt;  &lt;p&gt;In the agile software world we often use the mantra…”do the simplest thing that works”.&amp;#160; I have found that I cringe at the usage of that statement at certain points (when honest - even at my own usage at times upon later reflection).&amp;#160; Really, if we step back and honestly evaluate ourselves, how often do we really implement the simplest thing that works. My opinion is that it’s often used as an excuse to get get out of work - a “wild card” of sorts that’s pulled out when convenient.&lt;/p&gt;  &lt;p&gt;With “the simplest thing that works”, developers associate the term YAGNI – You Ain’t Gonna Need It.&amp;#160; While very often true – you really don’t need that feature (studies have demonstrated and confirmed) – I see times where people confuse YAGNI and the agile principle of “the simplest thing that works”. What’s the difference? &lt;/p&gt;  &lt;p&gt;Chess versus checkers my friend. Checkers is a pretty simple game with few rules and even fewer game pieces.&amp;#160; Chess however has several game pieces, each of which has their own movements and rules associated with them.&amp;#160; The types of discussions and strategies that exist around chess do not exist around checkers.&amp;#160; Put simply, chess is much more complex than checkers.&amp;#160; Checkers is really treated on a move-by-move basis whereas chess is far more strategic, where moves are setup far in advance of their execution.&lt;/p&gt;  &lt;p&gt;When talking about “the simplest thing that works” we have to be careful to not be playing checkers.&amp;#160; Play chess instead.&amp;#160; Make a small, single move that moves you closer to some strategic end.&amp;#160; Like it or not, many waterfall processes are playing chess – trying to anticipate every outcome or piece of functionality and adjust/account for it. What the waterfall practitioner fails to see is the inevitable change.&amp;#160; Many agile adopters start playing checkers, making small move after small move, assuaging fears of downstream problems with the comfort that their doing the simplest thing that works.&lt;/p&gt;  &lt;p&gt;Therefore, have a strategy, a end in mind, and then do the simplest thing that works that moves you closer to that end.&amp;#160; Note however that this may not always be the absolute simplest thing that works.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55956" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/kbVzf_O85Ec" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Musings/default.aspx">Musings</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Methodology/default.aspx">Methodology</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2010/03/15/are-you-playing-checker-or-chess-yagni-revisited.aspx</feedburner:origLink></item><item><title>UppercuT – Custom Extensions Now With PowerShell and Ruby</title><link>http://feedproxy.google.com/~r/Devlicious/~3/GyPWm75HD3o/uppercut-custom-extensions-now-with-powershell-and-ruby.aspx</link><pubDate>Sun, 14 Mar 2010 01:43:27 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55934</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_12EE92D6.png"&gt;&lt;img style="border-right-width:0px;margin:5px 0px 10px 5px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="UppercuT Logo. With attributions to Microsoft for PowerShell Logo and Ruby Association for Ruby Logo" border="0" alt="UppercuT Logo. With attributions to Microsoft for PowerShell Logo and Ruby Association for Ruby Logo" align="right" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_06409A20.png" width="244" height="176" /&gt;&lt;/a&gt; Arguably, one of the most powerful features of &lt;a href="http://projectuppercut.org" target="_blank"&gt;UppercuT&lt;/a&gt; (UC) is the ability to extend any step of the build process with a pre, post, or replace hook. This customization is done in a separate location from the build so you can upgrade without wondering if you broke the build.&lt;/p&gt;  &lt;p&gt;There is a hook before each step of the build has run. There is a hook after. And back to power again, there is a replacement hook. If you don’t like what the step is doing and/or you want to replace it’s entire functionality, you just drop a custom replacement extension and UppercuT will perform the custom step instead.&lt;/p&gt;  &lt;p&gt;Up until recently all custom hooks had to be written in &lt;a href="http://nant.sourceforge.net" target="_blank"&gt;NAnt&lt;/a&gt;. Now they are a little sweeter because you no longer need to use NAnt to extend UC if you don’t want to. You can use &lt;a href="http://go.microsoft.com/fwlink/?LinkID=107116" target="_blank"&gt;PowerShell&lt;/a&gt;. Or &lt;a href="http://www.ruby-lang.org/" target="_blank"&gt;Ruby&lt;/a&gt;.&amp;#160;&amp;#160; Let that sink in for a moment. You don’t have to even need to interact with NAnt at all now.&lt;/p&gt;  &lt;h4&gt;&lt;strong&gt;&lt;u&gt;Extension Points&lt;/u&gt;&lt;/strong&gt;&lt;/h4&gt;  &lt;p&gt;On the &lt;a href="http://uppercut.pbworks.com/"&gt;wiki&lt;/a&gt;, all of the &lt;a href="http://uppercut.pbworks.com/CustomizeUsingExtensionPoints"&gt;extension points&lt;/a&gt; are shown. The basic idea is that you would put whatever customization you are doing in a separate folder named build.custom. Each step Let’s take a look at all we can customize:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The start point is &lt;strong&gt;default.build. &lt;/strong&gt;It calls build.custom/default.&lt;strong&gt;pre&lt;/strong&gt;.build if it exists, then it runs build/default.build (normal tasks) OR build.custom/default.&lt;strong&gt;replace&lt;/strong&gt;.build if it exists, and finally build.custom/default.&lt;strong&gt;post&lt;/strong&gt;.build if it exists. Every step below runs with the same extension points but changes on the file name it is looking for. &lt;strong&gt;NOTE: If you include default.replace.build, nothing else will run because everything is called from default.build.&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;policyChecks.step &lt;/li&gt;        &lt;li&gt;versionBuilder.step &lt;strong&gt;NOTE: If you include build.custom/versionBuilder.replace.step, the items below will not run.&lt;/strong&gt;           &lt;ul&gt;           &lt;li&gt;svn.step, tfs.step, or git.step (the custom tasks for these need to go in build.custom/versioners) &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;generateBuildInfo.step &lt;/li&gt;        &lt;li&gt;compile.step &lt;/li&gt;        &lt;li&gt;environmentBuilder.step &lt;/li&gt;        &lt;li&gt;analyze.step &lt;strong&gt;NOTE: If you include build.custom/analyze.replace.step, the items below will not run.&lt;/strong&gt;           &lt;ul&gt;           &lt;li&gt;test.step (the custom tasks for this need to go in build.custom/analyzers) &lt;strong&gt;NOTE: If you include build.custom/analyzers/test.replace.step, the items below will not run.&lt;/strong&gt;               &lt;ul&gt;               &lt;li&gt;mbunit2.step, gallio.step, or nunit.step (the custom tasks for these need to go in build.custom/analyzers) &lt;/li&gt;             &lt;/ul&gt;           &lt;/li&gt;            &lt;li&gt;ncover.step (the custom tasks for this need to go in build.custom/analyzers) &lt;/li&gt;            &lt;li&gt;ndepend.step (the custom tasks for this need to go in build.custom/analyzers) &lt;/li&gt;            &lt;li&gt;moma.step (the custom tasks for this need to go in build.custom/analyzers) &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;package.step &lt;strong&gt;NOTE: If you include build.custom/package.replace.step, the items below will not run.&lt;/strong&gt;           &lt;ul&gt;           &lt;li&gt;deploymentBuilder.step &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;&lt;strong&gt;&lt;u&gt;Customize UppercuT Builds With PowerShell&lt;/u&gt;&lt;/strong&gt;&lt;/h4&gt;  &lt;p&gt;UppercuT can now be extended with PowerShell (PS). To customize any extension point with PS, just add &lt;strong&gt;.ps1&lt;/strong&gt; to the end of the file name and write your custom tasks in PowerShell.&lt;/p&gt;  &lt;p&gt;If you are not signing your scripts you will need to change a setting in the &lt;a href="http://uppercut.pbworks.com/UppercuT_config"&gt;UppercuT.config&lt;/a&gt; file. This does impose a security risk, because this allows PS to now run any PS script. This setting stays that way on &lt;strong&gt;ANY&lt;/strong&gt; machine that runs the build until manually changed by someone. I’m not responsible if you mess up your machine or anyone else’s by doing this. You’ve been warned.&lt;/p&gt;  &lt;p&gt;Now that you are fully aware of any security holes you may open and are okay with that, let’s move on. &lt;/p&gt;  &lt;p&gt;Let’s create a file called &lt;strong&gt;default.replace.build.ps1&lt;/strong&gt; in the &lt;strong&gt;build.custom&lt;/strong&gt; folder.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_51BFC7D7.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="default.replace.build.ps1" border="0" alt="default.replace.build.ps1" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_74C0137A.png" width="371" height="360" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Open that file in notepad and let’s add this to it:&lt;/p&gt;  &lt;pre&gt;write-host &amp;quot;hello - I&amp;#39;m a custom task written in Powershell!&amp;quot;&lt;/pre&gt;

&lt;p&gt;Now, let’s run build.bat.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_1DE7ABB9.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="I&amp;#39;m a custom task written in PowerShell!" border="0" alt="I&amp;#39;m a custom task written in PowerShell!" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_787DB84A.png" width="511" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You could get some &lt;a href="http://code.google.com/p/psake/"&gt;PSake&lt;/a&gt; action going here. I won’t dive into that in this post though.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;&lt;u&gt;Customize UppercuT Builds With Ruby&lt;/u&gt;&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;If you want to customize any extension point with Ruby, just add &lt;strong&gt;.rb&lt;/strong&gt; to the end of the file name and write your custom tasks in Ruby.&amp;#160; Let’s write a custom ruby task for UC. If you were thinking it would be the same as the one we just wrote for PS, you’d be right! &lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;build.custom&lt;/strong&gt; folder, lets create a file called &lt;strong&gt;default.replace.build.rb&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_227DB673.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="default.replace.build.rb. Ya. Ruby" border="0" alt="default.replace.build.rb. Ya. Ruby" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_7992A169.png" width="330" height="273" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Open that file in notepad and let’s put this in there:&lt;/p&gt;

&lt;pre class="ruby" name="code"&gt;puts &amp;quot;I&amp;#39;m a custom ruby task!&amp;quot;&lt;/pre&gt;

&lt;p&gt;Now, let’s run build.bat again.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_65990ED3.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="I&amp;#39;m a custom ruby task!" border="0" alt="I&amp;#39;m a custom ruby task!" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_5C5CD392.png" width="665" height="269" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;That’s chunky bacon.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;&lt;u&gt;UppercuT and Albacore.NET&lt;/u&gt;&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Just for fun, I wanted to see if I could replace the compile.step with a Rake task. Not just any rake task, &lt;a href="http://albacorebuild.net/"&gt;Albacore’s&lt;/a&gt; msbuild task. &lt;a href="http://albacorebuild.net/"&gt;Albacore&lt;/a&gt; is a suite of rake tasks brought about by &lt;a href="http://www.lostechies.com/blogs/derickbailey"&gt;Derick Bailey&lt;/a&gt; to make building .NET with Rake easier. It has quite a bit of support with developers that are using Rake to build code. &lt;/p&gt;

&lt;p&gt;In my build.custom folder, I drop a compile.replace.step.rb. I also put in a separate file that will contain my Albacore rake task and I call that compile.rb.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_68EA80AE.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="compile.replace.step.rb" border="0" alt="compile.replace.step.rb" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_4CF94BB6.png" width="424" height="369" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;What are the contents of &lt;strong&gt;compile.replace.step.rb&lt;/strong&gt;?&lt;/p&gt;

&lt;pre class="ruby" name="code"&gt;rake = &amp;#39;rake&amp;#39;
arguments= &amp;#39;-f &amp;#39; + Dir.pwd + &amp;#39;/../build.custom/compile.rb&amp;#39;

#puts &amp;quot;Calling #{rake} &amp;quot; + arguments
system(&amp;quot;#{rake} &amp;quot; + arguments)&lt;/pre&gt;

&lt;p&gt;Since the custom extensions call ruby, we have to shell back out and call rake. That’s what we are doing here. We also realize that ruby is called from the build folder, so we need to back out and dive into the build.custom folder to find the file that is technically next to us.&lt;/p&gt;

&lt;p&gt;What are the contents of &lt;strong&gt;compile.rb&lt;/strong&gt;?&lt;/p&gt;

&lt;pre class="ruby" name="code"&gt;require &amp;#39;rubygems&amp;#39;
require &amp;#39;fileutils&amp;#39;
require &amp;#39;albacore&amp;#39;

task :default =&amp;gt; [:compile]

puts &amp;quot;Using Ruby to compile UppercuT with Albacore Tasks&amp;quot;
desc &amp;#39;Compile the source&amp;#39;
msbuild :compile do |msb|
  msb.properties = { :configuration =&amp;gt; :Release, :outputpath =&amp;gt; &amp;#39;../../build_output/UppercuT&amp;#39; }
  msb.targets [:clean, :build]
  msb.verbosity = &amp;quot;quiet&amp;quot;
  msb.path_to_command = &amp;#39;c:/Windows/Microsoft.NET/Framework/v3.5/MSBuild.exe&amp;#39;
  msb.solution = &amp;#39;../uppercut.sln&amp;#39;
end&lt;/pre&gt;

&lt;p&gt;We are using the msbuild task here. We change the output path to the build_output/UppercuT folder. The output path has “../../” because this is based on every project. We could grab the current directory and then point the task specifically to a folder if we have projects that are at different levels. We want the verbosity to be quiet so we set that as well.&lt;/p&gt;

&lt;p&gt;So what kind of output do you get for this? Let’s run build.bat&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;custom_tasks_replace: &lt;/p&gt;

  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [echo] Running custom tasks instead of normal tasks if C:\code\uppercut\build\..\build.custom\compile.replace.step exists. 
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [exec] (in C:/code/uppercut/build) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [exec] &lt;strong&gt;Using Ruby to compile UppercuT with Albacore Tasks&lt;/strong&gt; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [exec] Microsoft (R) Build Engine Version 3.5.30729.4926 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [exec] [Microsoft .NET Framework, Version 2.0.50727.4927] 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [exec] Copyright (C) Microsoft Corporation 2007. All rights reserved.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you think this is awesome, you’d be right!&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;With this knowledge you shall build.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55934" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/GyPWm75HD3o" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/UppercuT/default.aspx">UppercuT</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><feedburner:origLink>http://devlicio.us/blogs/rob_reynolds/archive/2010/03/13/uppercut-custom-extensions-now-with-powershell-and-ruby.aspx</feedburner:origLink></item><item><title>Come Hang at Mix…MVVM Style</title><link>http://feedproxy.google.com/~r/Devlicious/~3/zpIrkynnJcU/come-hang-at-mix-mvvm-style.aspx</link><pubDate>Sun, 14 Mar 2010 00:07:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55933</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Tomorrow I kiss the wife and baby goodbye (sadly) and hop on a plane heading to &lt;a href="http://live.visitmix.com/"&gt;Mix in Las Vegas&lt;/a&gt;.&amp;nbsp; This year I have the unique honor and privilege to present &lt;a href="http://live.visitmix.com/MIX10/Sessions/EX15"&gt;&amp;ldquo;Build Your Own MVVM Framework.&amp;rdquo;&lt;/a&gt;&amp;nbsp; I&amp;rsquo;ll be speaking Monday afternoon at 3:30 PM in Lagoon F.&amp;nbsp; Here&amp;rsquo;s the official description of my talk:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You&amp;rsquo;ve heard a lot about MVVM, but you&amp;rsquo;ve struggled to see how it can help you in your day to day work. Or, you are experienced at implementing MVVM, but looking for some ways to maximize on your investment in this methodology. In this talk, we look at a simple MVVM application and see how a small, application-specific framework can help eliminate pain points in our UI development and provide simple and effective solutions. Attendees will walk away with code, but more importantly with an understanding of how to apply some simple ideas to improve productivity with MVVM in their own projects.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is an intermediate level discussion of MVVM and presupposes knowledge of either WPF or Silverlight and a grasp of the basic MVVM pattern.&amp;nbsp; If you are new to MVVM, let me encourage you to attend Laurent Bugnion&amp;rsquo;s talk &lt;a href="http://live.visitmix.com/MIX10/Sessions/EX14"&gt;&amp;ldquo;Understanding the Model-View-ViewModel Pattern,&amp;rdquo;&lt;/a&gt; conveniently scheduled just before me at 2:00pm in Lagoon F.&lt;/p&gt;
&lt;p&gt;During the conference, I&amp;rsquo;m planning to spend plenty of time in the lounge.&amp;nbsp; I&amp;rsquo;ll probably be working on &lt;a href="http://caliburn.codeplex.com/"&gt;Caliburn&lt;/a&gt; :)&amp;nbsp; If you&amp;rsquo;re interested in &lt;a href="http://caliburnproject.org/"&gt;Caliburn&lt;/a&gt; and will be at &lt;a href="http://live.visitmix.com/"&gt;Mix&lt;/a&gt;, let me know.&amp;nbsp; If there is enough interest, I can do a small demo/presentation in the lounge at some point.&amp;nbsp; I&amp;rsquo;m looking forward to seeing you there and thank you to everyone who voted for my talk!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55933" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/zpIrkynnJcU" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><feedburner:origLink>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/13/come-hang-at-mix-mvvm-style.aspx</feedburner:origLink></item><item><title>Versioning REST Services</title><link>http://feedproxy.google.com/~r/Devlicious/~3/-CX5PYdehtI/versioning-rest-services.aspx</link><pubDate>Sat, 13 Mar 2010 19:01:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55926</guid><dc:creator>Scott Seely</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I&amp;rsquo;ve always been intrigued by the versioning problem. The versioning problem works like this: you build an API (Application Programming Interface) to get some work done. That API is successful and consumers ask for enhancements to the API. At this point, you have a problem: how do you support everyone who uses the current API while adding enhancements? If you have been down this road, you know that you have to solve the problem early&amp;mdash;before success. &lt;/p&gt;
&lt;p&gt;The way you handle versioning varies. With compiled code and libraries, you send out a new DLL/Assembly/JAR file and tell folks to convert existing code when they have a chance. With Web services, including SOAP, REST, and just HTTP accessible ones, you have other issues. You typically want a single code base to consume the old and updated messages. Given that many of us are now writing REST services, I talked to InformIT about the need for an article explaining how to version these JSON/XML speaking endpoints. That article is now live and available for your reading at &lt;a href="http://www.informit.com/articles/article.aspx?p=1566460" title="http://www.informit.com/articles/article.aspx?p=1566460"&gt;http://www.informit.com/articles/article.aspx?p=1566460&lt;/a&gt;. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55926" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/-CX5PYdehtI" height="1" width="1"/&gt;</description><feedburner:origLink>http://devlicio.us/blogs/scott_seely/archive/2010/03/13/versioning-rest-services.aspx</feedburner:origLink></item><item><title>ASP.NET: Cannot use a leading .. to exit above the top directory</title><link>http://feedproxy.google.com/~r/Devlicious/~3/SX5S1xeWidA/asp-net-cannot-use-a-leading-to-exit-above-the-top-directory.aspx</link><pubDate>Fri, 12 Mar 2010 20:09:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55902</guid><dc:creator>Michael C. Neel</dc:creator><slash:comments>4</slash:comments><description>&lt;p&gt;&lt;a title="Caen como moscas by Eduardo!" href="http://www.flickr.com/photos/eduardox/2315932412/"&gt;&lt;img style="border-right-width:0px;margin:0px 10px 10px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" align="left" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/vinull/image_5F00_28F0EF6F.png" width="244" height="184" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is a really quick post, mostly for myself so the next time I have this issue I can find the answer (yes, I often search my blog before google).&lt;/p&gt;  &lt;p&gt;The error “Cannot use a leading .. to exit above the top directory” can be thrown by ASP.NET when you use relative paths incorrectly.&amp;#160; If you generate a url with too many “../../../” levels in it that would take the user above the root directory, you can generate the exception.&lt;/p&gt;  &lt;p&gt;Why the exception?&amp;#160; Security I guess, but it’s a client URL and the server should know better than let the internet walk the C drive, but at one time a company in Redmond had servers with just such issues.&amp;#160; My problem isn’t with the unneeded exception (after all, it would just be a 404 link worst case), but with the bug in ASP.NET that causes it.&lt;/p&gt;  &lt;p&gt;If you are using Server.Transfer or HttpContext.RewritePath to redirect a request (say map it to a template page) and have a HyperLink control with the ImageUrl property set, you win an extra “../” by the framework.&amp;#160; The fix is to wrap the HyperLink control around an Image control.&amp;#160; &lt;/p&gt;  &lt;p&gt;In code, if you have:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;asp&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;HyperLink&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;runat&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;NavigateUrl&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;~/FlyPage.aspx&amp;quot;&lt;/span&gt;&lt;span style="background:#ffee62;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#ff0000;"&gt;ImageUrl&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;~/Images/DeadFly.png&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Width&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Height&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;200&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change it to:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;asp&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;HyperLink&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;runat&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;NavigateUrl&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;~/FlyPage.aspx&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background:#ffee62;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;asp&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Image&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;runat&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;ImageUrl&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;~/Images/DeadFly.png&amp;quot;&lt;/span&gt;&lt;span style="background:#ffee62;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#ff0000;"&gt;Width&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Height&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;asp&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;HyperLink&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;(I said it was a quick post… now go register for &lt;a href="http://codestock.org"&gt;CodeStock&lt;/a&gt;!)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55902" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/SX5S1xeWidA" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/vinull/archive/tags/asp.net/default.aspx">asp.net</category><feedburner:origLink>http://devlicio.us/blogs/vinull/archive/2010/03/12/asp-net-cannot-use-a-leading-to-exit-above-the-top-directory.aspx</feedburner:origLink></item><item><title>dotTrace 3.1 64-bit disabled inside Visual Studio 2008</title><link>http://feedproxy.google.com/~r/Devlicious/~3/9x9TI6CxJpE/dottrace-3-1-64-bit-disabled-inside-visual-studio-2008.aspx</link><pubDate>Fri, 12 Mar 2010 18:15:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55898</guid><dc:creator>sergiopereira</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;
I work on a web application and I use &lt;a href="http://www.jetbrains.com/profiler/"&gt;dotTrace&lt;/a&gt; 
when some profiling is needed. The problem is that I cannot fire off doTrace directly from inside Visual
Studio 2008 because the commands and toolbar icons to launch it are permanently disabled. Well, not anymore.
&lt;/p&gt;

&lt;h3&gt;Background&lt;/h3&gt;
&lt;p&gt;
The web application I work on is a 64-bit application. I use a 64-bit version of Windows (namely, Win2008 x64).
I installed the 64-bit version of dotTrace 3.1 and it does work stand-alone but it never worked integrated with
VS 2008, which is a shame because it contains some neat features like it&amp;#39;s enabling the ReSharper test runner
to run the chosen test(s) directly under dotTrace profiling. The screen shot below shows how it should look like
but on my box these dotTrace commands were simply disabled.
&lt;/p&gt;

&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.03/dottrace_2D00_64.png" alt="" /&gt;&lt;/p&gt;

&lt;h3&gt;The fix&lt;/h3&gt;
&lt;p&gt;
After much disappointment with the missing features, my fellow &lt;a href="http://devlicio.us/"&gt;Devlicio.us&lt;/a&gt;
blogger &lt;a href="http://devlicio.us/blogs/hadi_hariri/"&gt;Hadi Hariri&lt;/a&gt; put me in contact with 
&lt;a href="http://blogs.jetbrains.com/nocturne/"&gt;Oleg Stepanov&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
The first suggestion was trying the 32-bit version of dotTrace, which wasn&amp;#39;t an option for
me because, as I said, my application and all the supporting utilities are 64-bit, 
it runs under a 64-bit process, so that&amp;#39;s ultimately how I need to profile it.
&lt;/p&gt;

&lt;p&gt;
Then Oleg explained that the problem is that VS is a 32-bit application and it
was looking for a registry key in the wrong place, not finding it, and then
it was assuming dotTrace wasn&amp;#39;t available.
&lt;/p&gt;

&lt;p&gt;
 Hmmm... That sounded 
 &lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/07/20/resharper-test-runner-in-64-bit-windows.aspx"&gt;eerily familiar&lt;/a&gt;, didn&amp;#39;t it? Once again the little annoyances of developing 64-bit code with
 32-bit tools come to bite us.
&lt;/p&gt;

&lt;p&gt;
To fix the problem, just like 
&lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/07/20/resharper-test-runner-in-64-bit-windows.aspx"&gt;the other time it happened&lt;/a&gt;, we just need to copy the right registry key to its
corresponding place under the Wow6432Node key. 
&lt;/p&gt;

&lt;p&gt;
Open the Registry Editor and go to the
&lt;code&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\&lt;/code&gt; key.
One of its GUID-named subkeys will contain the dotTrace information. Just search for dotTrace 
and find the right subkey. Now just copy (or export/edit/import) that key under 
&lt;code&gt;HKEY_LOCAL_MACHINE\SOFTWARE\&lt;b&gt;&lt;u&gt;Wow6432Node&lt;/u&gt;&lt;/b&gt;\Microsoft\Windows\CurrentVersion\Uninstall\&lt;/code&gt;
and you&amp;#39;re ready to restart Visual Studio and see all the integrated dotTrace features
come alive.
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55898" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/9x9TI6CxJpE" height="1" width="1"/&gt;</description><feedburner:origLink>http://devlicio.us/blogs/sergio_pereira/archive/2010/03/12/dottrace-3-1-64-bit-disabled-inside-visual-studio-2008.aspx</feedburner:origLink></item><item><title>Advanced Castle Windsor – generic typed factories, auto-release and more</title><link>http://feedproxy.google.com/~r/Devlicious/~3/5zeLmTFVhkY/advanced-castle-windsor-generic-typed-factories-auto-release-and-more.aspx</link><pubDate>Thu, 11 Mar 2010 20:13:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55870</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;This post is a playground for me, to try out some ideas I want to include in my talk about Windsor at &lt;a href="http://ms-groups.pl/kgd.net/default.aspx"&gt;KGD.NET&lt;/a&gt; meeting later this month.&lt;/p&gt;
&lt;h3&gt;Scenario&lt;/h3&gt;
&lt;p&gt;We have a messaging application built around two interfaces:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:500px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; Command&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; Handler&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Execute();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; Handler&amp;lt;T&amp;gt; : Handler &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : Command&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    T Command { get; set; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Hopefully I don&amp;rsquo;t have to explain how they work. The idea is, application receives commands from somewhere, then it pulls all handlers registered for this command and let them handle the command. Split of Handler interface into generic and non-generic part is there to make up for lack of co/contra-variance in .NET 3.5.&lt;/p&gt;
&lt;h3&gt;Commands and Handlers&lt;/h3&gt;
&lt;p&gt;Handlers are quite simple classes implementing closed version of Handler&amp;lt;&amp;gt; interface. For example to change client&amp;rsquo;s address we&amp;rsquo;d have the following command&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;[Serializable]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; UpdateClientCorrespondenceAddressCommand : Command&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; AddressDto address;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; Guid clientId;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; UpdateClientCorrespondenceAddressCommand(Guid clientId, AddressDto address)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.clientId = clientId;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.address = address;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; AddressDto Address&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; address; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Guid ClientId&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; clientId; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and its handler:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; UpdateClientCorrespondenceAddressHandler : Handler&amp;lt;UpdateClientCorrespondenceAddressCommand&amp;gt;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; Repository&amp;lt;Client&amp;gt; clientRepository;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; UpdateClientCorrespondenceAddressHandler(Repository&amp;lt;Client&amp;gt; clientRepository)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.clientRepository = clientRepository;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; UpdateClientCorrespondenceAddressCommand Command { get; set; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Execute()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var command = Command;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (command == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var client = clientRepository.Get(command.ClientId);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        client.ChangeCorrespondenceAddress(command.Address);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        clientRepository.Update(client);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Nothing earth shattering here. We would have similar set up for other business events in the application. We assume we can have more than one handler for single command (for example another handler would update shipping costs and promotions available for the new address of the client).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The ability to pull multiple services from the container via typed factory is not available in Windsor 2.1.1 &amp;ndash; you need the trunk version to take advantage of it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;Registration&lt;/h3&gt;
&lt;p&gt;To register the code we create an installer:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;height:354px;max-height:350px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Installer : IWindsorInstaller&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Install(IWindsorContainer container, IConfigurationStore store)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        container.AddFacility&amp;lt;TypedFactoryFacility&amp;gt;()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            .Register(&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                Component.For&amp;lt;ITypedFactoryComponentSelector&amp;gt;().ImplementedBy&amp;lt;HandlerSelector&amp;gt;(),&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                Component.For&amp;lt;AutoReleaseHandlerInterceptor&amp;gt;(),&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                AllTypes.FromAssemblyContaining&amp;lt;Program&amp;gt;()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                    .BasedOn(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Repository&amp;lt;&amp;gt;))&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                    .WithService.Base()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                    .Configure(c =&amp;gt; c.LifeStyle.Singleton)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                    .BasedOn(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Handler&amp;lt;&amp;gt;))&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                    .WithService.Base()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                    .Configure(c =&amp;gt; c.LifeStyle.Is(LifestyleType.Transient)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                                        .Interceptors&amp;lt;AutoReleaseHandlerInterceptor&amp;gt;()),&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                Component.For&amp;lt;HandlerFactory&amp;gt;().AsFactory());&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There are a couple interesting things here. First we register &lt;a href="http://kozmic.pl/archive/2009/12/24/castle-typed-factory-facility-reborn.aspx"&gt;typed factory facility&lt;/a&gt;, which we&amp;rsquo;ll use later on to pull handlers for commands we receive. Then we register custom selector for typed factory (discussed below), and an interceptor (discussed below). Then we&amp;nbsp; register all repositories and all handlers from given assembly, configuring handlers with transient lifestyle and with the interceptor we registered above. Lastly we also register typed factory for handlers:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; HandlerFactory&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    Handler[] GetHandlersForCommand(Command command);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;Typed factory selector&lt;/h3&gt;
&lt;p&gt;The handler factory has to do quite a lot of work for us. Given an instance of a command, it has to pull from the container all the handlers for the command&amp;rsquo;s type. To do this we need to use a custom selector (and trunk version of Windsor).&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; HandlerSelector:ITypedFactoryComponentSelector&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TypedFactoryComponent SelectComponent(MethodInfo method, Type type, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[] arguments)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Debug.Assert(arguments.Length == 1);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var message = arguments[0];&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var handlerType = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Handler&amp;lt;&amp;gt;).MakeGenericType(message.GetType());&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TypedFactoryComponentCollection(handlerType.MakeArrayType(), &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Arguments(arguments));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Based on the command&amp;rsquo;s type we create closed Handler&amp;lt;&amp;gt; type and return TypedFactoryComponentCollection (new type that pulls all components for given service) passing down the command as typed argument to the resolution. &lt;/p&gt;
&lt;h3&gt;Putting it all together&lt;/h3&gt;
&lt;p&gt;We can now use the code like this:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;height:437px;max-height:600px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;(var container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; WindsorContainer().Install(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Installer()))&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var factory = container.Resolve&amp;lt;HandlerFactory&amp;gt;();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        DoActualWork(factory);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Console.ReadKey(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoActualWork(HandlerFactory factory)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    var command = ImmitateCommandArrived();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    var handlers = factory.GetHandlersForCommand(command);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var handler &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; handlers)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        handler.Execute();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; Command ImmitateCommandArrived()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UpdateClientCorrespondenceAddressCommand(Guid.NewGuid(), GetSomeAddress());&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Notice how simple the calling code is. It has no knowledge of the (quite complex) process that takes place behind the scenes to create strongly typed instances of appropriate classes. It does not even know what actual type of command it got.&lt;/p&gt;
&lt;h3&gt;What about releasing transient handlers?&lt;/h3&gt;
&lt;p&gt;Isn&amp;rsquo;t this code too simple though? It resolves handlers, which are transient components and it does not release them. And we all know transient components need to be released in Windsor, right?&lt;/p&gt;
&lt;p&gt;Well &amp;ndash; it does release them actually, it just doesn&amp;rsquo;t do it explicitly. Remember we registered an interceptor with all handlers. Here&amp;rsquo;s how that interceptor looks like:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;height:255px;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;[Transient]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; AutoReleaseHandlerInterceptor : IInterceptor&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; MethodInfo Execute = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Handler).GetMethod(&lt;span style="color:#006080;"&gt;&amp;quot;Execute&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; IKernel kernel;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; AutoReleaseHandlerInterceptor(IKernel kernel)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.kernel = kernel;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Intercept(IInvocation invocation)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;(invocation.Method!=Execute)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            invocation.Proceed();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            invocation.Proceed();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;finally&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            kernel.ReleaseComponent(invocation.Proxy);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The interceptor releases the component after the call to Execute for us. Thanks to this we take the burden (no pun intended) of releasing the components from the callers, and we make sure our handlers won&amp;rsquo;t leak memory. This is quite a useful trick actually, and while I have precisely zero knowledge of &lt;a href="http://www.nservicebus.com/"&gt;NServiceBus&lt;/a&gt;, I think it could be used to fix &lt;a href="http://davybrion.com/blog/2010/02/avoiding-memory-leaks-with-nservicebus-and-your-own-castle-windsor-instance/"&gt;the issue Davy discussed&lt;/a&gt;, without having to mess with release policy.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55870" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/5zeLmTFVhkY" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Castle/default.aspx">Castle</category><feedburner:origLink>http://devlicio.us/blogs/krzysztof_kozmic/archive/2010/03/11/advanced-castle-windsor-generic-typed-factories-auto-release-and-more.aspx</feedburner:origLink></item><item><title>Zen Coding and ReSharper PowerToys</title><link>http://feedproxy.google.com/~r/Devlicious/~3/s3_dffftUdk/zen-coding-and-resharper-powertoys.aspx</link><pubDate>Thu, 11 Mar 2010 11:25:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55858</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Yesterday the &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt;&amp;nbsp;&lt;a href="http://twitter.com/resharper"&gt;Twitter Account&lt;/a&gt; tweeted about a Zen Coding Plug-in available as a PowerToy. If you&amp;rsquo;re not familiar with Zen Coding, &lt;a href="http://vimeo.com/7405114"&gt;check out this link&lt;/a&gt;. I received a couple of emails from people asking about the PowerToys and what exactly they were, and to be honest, I wasn&amp;rsquo;t really surprised. I don&amp;rsquo;t think many have actually heard of them. So I decided to follow &lt;a href="http://www.hanselman.com/"&gt;Hanselman&amp;rsquo;s&lt;/a&gt; advice of minimizing key strokes, thus the post.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;What are they?&lt;/h4&gt;
&lt;p&gt;The Power Toys are a series of plug-ins that have been written by the ReSharper developer team, and have been used in fact internally as samples of ReSharper&amp;rsquo;s API. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Where can I get them and how do I install them?&lt;/h4&gt;
&lt;p&gt;You can download the PowerToys for ReSharper 5 from the Early Access Program page (for previous versions, see What next?), which is &lt;a href="http://www.jetbrains.net/confluence/display/ReSharper/ReSharper+5.0+Nightly+Builds"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_41FBCBC7.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_38AF6AB9.png" border="0" height="272" width="527" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Unless there&amp;rsquo;s some API change, there are normally compatible from one build to the next, but just to be safe, download the one corresponding to the nightly build you have. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_34756D27.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_36EE7918.png" border="0" height="340" width="479" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;They are packaged up in a zip file that contains MSI installers for each individual plug-in, as well as a PowerToys Pack which includes them all (and you can pick and choose which one you want during the installation process). Best option is to just pick the full pack. Each MSI is also suffixed with a version, 8 corresponding to Visual Studio 2005, 9 to 2008 and 10 to 2010. &lt;/p&gt;
&lt;p&gt;The zip file also contains another zip with the source code, which you can compile and install, if you don&amp;rsquo;t want to use an installer. If you&amp;rsquo;re doing this, compile them and place them under the %Program files%\&lt;a href="http://www.jetbrains.com"&gt;JetBrains&lt;/a&gt;\ReSharper\Bin\Plugins folder. Normally best to create a folder for each plug-in (If you&amp;rsquo;re just interested in having the source but prefer to use the MSI, the installer will also install the source for you).&lt;/p&gt;
&lt;p&gt;Once you install them, they should appear as plug-ins under the ReSharper menu:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_7D2B9393.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_19D4E2DC.png" border="0" height="350" width="426" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you can see from the list, there are quite a few goodies in there, not only Zen Coding! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;What next? &lt;/h4&gt;
&lt;p&gt;The PowerToys are not only valuable in terms of the functionality they provide, but also serve as an example of how to write ReSharper plug-ins and interact with the ReSharper API, but they&amp;rsquo;ve never been released passed Early Access Programs. That is one reason 4.5 PowerToys are not available. &lt;/p&gt;
&lt;p&gt;However, we want to change that. We not only want to make them available, but also to document them and offer them as a true OSS project, where the developer community can contribute to them, be it with additional features, bug fixes or providing completely new plug-ins. &lt;/p&gt;
&lt;p&gt;This is something that I personally think would be valuable for the community. If you like this idea or have other suggestions, please feel free to give me feedback. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55858" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/s3_dffftUdk" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ReSharper/default.aspx">ReSharper</category><feedburner:origLink>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/11/zen-coding-and-resharper-powertoys.aspx</feedburner:origLink></item><item><title>Sharing Code Analysis files between projects in Visual Studio 2010</title><link>http://feedproxy.google.com/~r/Devlicious/~3/wMHafScmAa4/sharing-code-analysis-files-between-projects-in-visual-studio-2010.aspx</link><pubDate>Wed, 10 Mar 2010 11:13:43 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55827</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;The ability to have static code analysis (aka run FXCop inside the IDE) is not something that is new to Visual Studio 2010.&amp;#160; What is new is the simplicity in which you can share the exact same configuration across all of your projects at once.&lt;/p&gt;  &lt;p&gt;Prior to VS2010 if you wanted to share your config it was not possible (from what I have ever seen).&amp;#160; With VS2008 each .proj file contained a section in the file which laid out each rule that should/should not be turned on.&amp;#160; If you wanted to share these what you needed to do was open up each .proj file in a text editor and copy/paste the rules.&amp;#160; As you could image, copy and pasting this could get old real fast.&amp;#160; In fact I would even argue that I may even prevent you from wanted to use the built in analysis all together.&lt;/p&gt;  &lt;p&gt;Here comes Visual Studio 2010 to the rescue.&amp;#160; In 2010 you can save your rules to a .ruleset file and you can import this same file into all your projects.&amp;#160; No more need for copy/paste by hand.&lt;/p&gt;  &lt;p&gt;Steps To Do This:&lt;/p&gt;  &lt;p&gt;Step 1: Open up the Code Analysis tab in the project properties.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_2521C5A0.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_6ED09D90.png" width="364" height="214" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Step 2: In the drop down choose Browse&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_0BF6459B.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_5FD948A9.png" width="364" height="223" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Step 3: Find your .ruleset file on disk&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_15FAC0F9.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_632ABA84.png" width="364" height="224" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Step 4: Rinse and Repeat for all your other projects.&lt;/p&gt;  &lt;p&gt;Now that having the ability to share your rule set across projects is painless you have NO excuse not to utilize this feature.&lt;/p&gt;  &lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55827" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/wMHafScmAa4" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/.Net+IDE/default.aspx">.Net IDE</category><feedburner:origLink>http://devlicio.us/blogs/derik_whittaker/archive/2010/03/10/sharing-code-analysis-files-between-projects-in-visual-studio-2010.aspx</feedburner:origLink></item><item><title>Help Save King’s Quest!</title><link>http://feedproxy.google.com/~r/Devlicious/~3/HjgJFOtyVqA/help-save-king-s-quest.aspx</link><pubDate>Wed, 10 Mar 2010 01:43:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55815</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;On February 28, 2010, Activision issued a Cease and Desist order against Phoenix Online Studios, creators of &amp;ldquo;The Silver Lining,&amp;rdquo; an unofficial sequel to the King&amp;#39;s Quest series&amp;nbsp; The sequel had, in 2005, been approved for non-commercial release by the owner of the King&amp;rsquo;s Quest IP, Vivendi Universal.&amp;nbsp; The team has been working on the 5-part episodic King&amp;rsquo;s Quest Sequel for &lt;strong&gt;&lt;em&gt;eight years&lt;/em&gt;&lt;/strong&gt; (they started before 2005).&amp;nbsp; They had just completed their final milestone and were preparing to submit the game for approval to Vivendi Universal right before Activision and Vivendi merged. Immediately upon acquisition of the King&amp;rsquo;s Quest IP, Activision shut down Phoenix Studios, with no intent to uphold the previous agreements.&lt;/p&gt;
&lt;p&gt;As a long time fan of adventure games, and someone who has always wanted a real sequel to KQ6, I am really saddened by this.&amp;nbsp; Personally, I plan not to have anything to do with Activision until they make this right.&amp;nbsp; I hope you will join me in this.&amp;nbsp; If you have a few minutes, please sign the online petition and consider sending a letter to Activision.&amp;nbsp; Resources are below.&amp;nbsp; Thank you.&amp;nbsp; Now, on with your regularly scheduled programming&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Online Petition:&lt;/strong&gt;    &lt;br /&gt;&lt;a href="http://www.petitionspot.com/petitions/savetsl/"&gt;http://www.petitionspot.com/petitions/savetsl/&lt;/a&gt;    &lt;br /&gt;&lt;strong&gt;Facebook Group:&lt;/strong&gt;    &lt;br /&gt;&lt;a href="http://www.facebook.com/group.php?gid=382202612795&amp;amp;ref=mf"&gt;http://www.facebook.com/group.php?gid=382202612795&amp;amp;ref=mf&lt;/a&gt;    &lt;br /&gt;&lt;strong&gt;MySpace Page:&lt;/strong&gt;    &lt;br /&gt;&lt;a href="http://www.myspace.com/savetsl"&gt;http://www.myspace.com/savetsl&lt;/a&gt;&lt;strong&gt;     &lt;br /&gt;Form Letter for Contacting Activision:&lt;/strong&gt;    &lt;br /&gt;&lt;a href="http://www.tsl-game.com/forum/index.php?topic=8406.0"&gt;http://www.tsl-game.com/forum/index.php?topic=8406.0&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55815" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/HjgJFOtyVqA" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/game+development/default.aspx">game development</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><feedburner:origLink>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/09/help-save-king-s-quest.aspx</feedburner:origLink></item><item><title>[ANN] Chicago ALT.NET shows Rake and Albacore</title><link>http://feedproxy.google.com/~r/Devlicious/~3/cBgEADBFcAg/ann-chicago-alt-net-shows-rake-and-albacore.aspx</link><pubDate>Tue, 09 Mar 2010 23:35:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55811</guid><dc:creator>sergiopereira</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;
I haven&amp;#39;t mentioned our meetings here in a while but our group has been going strong and enthusiastic all this time.
&lt;/p&gt;

&lt;p&gt;
Tomorrow, March 10&lt;sup&gt;th&lt;/sup&gt; our topic will be build scripts for .Net projects using Rake and Albacore. I&amp;#39;ve been 
using Rake and a little bit of Albacore in my own projects and I&amp;#39;m ready to say that it will take a very serious 
event to make me go back to NAnt or MSBuild.
&lt;/p&gt;

&lt;h3&gt;Introduction to Rake with Albacore.NET&lt;/h3&gt;
&lt;p&gt;
		&lt;span style="font-size:x-small;"&gt;6:00 pm&lt;/span&gt; 
		&lt;br /&gt;

		Pizza and networking time
&lt;/p&gt;
&lt;p&gt;
		&lt;span style="font-size:x-small;"&gt;6:30 pm&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
	How would you to write your build &lt;em&gt;scripts&lt;/em&gt; using a
	&lt;em&gt;scripting&lt;/em&gt; language instead of XML? In this month&amp;#39;s meeting
	we will see how the ease of programming in Ruby can be used
	to create a much more pleasant and extensible build script.

&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt; isn&amp;#39;t just for Rubyists or 
Alphageeks anymore. &lt;a href="http://albacorebuild.net/"&gt;Albacore&lt;/a&gt; helps bring 
the power and expresiveness of the Ruby language to the world of .NET build 
automation. Using Rake it&amp;#39;s never been easier to handle build automation, 
test execution, continuous integration and just about any task you need to 
automate for your build.&lt;/p&gt;
&lt;p&gt;
&lt;img style="margin-right:5px;" src="http://chicagoalt.net/content/images/events/michael-d-hall.jpg" alt="" align="left" /&gt;
&lt;a href="http://www.just3ws.com/%20"&gt;Michael D. Hall&lt;/a&gt; has been developing software 
on the Microsoft platform for over a decade. He&amp;#39;s been an Alt.NETter for years 
and is really enjoying the exposure to different ideas and concepts beyond the 
safe confines of the .NET world. Currently he&amp;#39;s a consultant working with Obtiva 
and has started a &lt;a href="http://www.clouddevelopersgroup.com/"&gt;Cloud Developer&amp;#39;s Group&lt;/a&gt; 
that meets monthly in McHenry county.&lt;/p&gt;

&lt;a href="http://altnetchicago.eventbrite.com" target="_blank"&gt;&lt;img border="0" src="http://www.eventbrite.com/registerbutton?eid=588872333" alt="Register for Introduction to Rake with Albacore.NET in Chicago, IL  on Eventbrite" /&gt;&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55811" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/cBgEADBFcAg" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Automation/default.aspx">Automation</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/alt.net/default.aspx">alt.net</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Announcement/default.aspx">Announcement</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Community/default.aspx">Community</category><feedburner:origLink>http://devlicio.us/blogs/sergio_pereira/archive/2010/03/09/ann-chicago-alt-net-shows-rake-and-albacore.aspx</feedburner:origLink></item><item><title>Silverlight Challenge: Creating a DependencyProperty</title><link>http://feedproxy.google.com/~r/Devlicious/~3/OSaWsctHArY/silverlight-challenge-creating-a-dependencyproperty.aspx</link><pubDate>Tue, 09 Mar 2010 20:36:39 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55803</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;The following code throws an exception. Can you spot the bug?&lt;/p&gt;  &lt;pre class="xml:nogutter:nocontrols" name="code"&gt;public class MyControl : Control
{
    public static DependencyProperty MyPropertyProperty = DependencyProperty.Register(
        &amp;quot;MyProperty&amp;quot;,
        typeof (double),
        typeof (MyControl),
        new PropertyMetadata(0));

    public double MyProperty
    {
        get { return (double) GetValue(MyPropertyProperty); }
        set { SetValue(MyPropertyProperty, value); }
    }
}&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55803" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/OSaWsctHArY" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Challenge/default.aspx">Challenge</category><feedburner:origLink>http://devlicio.us/blogs/christopher_bennage/archive/2010/03/09/silverlight-challenge-creating-a-dependencyproperty.aspx</feedburner:origLink></item><item><title>Profiling Apps 1 of N: The MVC ActionLink</title><link>http://feedproxy.google.com/~r/Devlicious/~3/pIzK9mwB1vY/profiling-apps-1-of-n-the-mvc-actionlink.aspx</link><pubDate>Tue, 09 Mar 2010 20:34:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55802</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>10</slash:comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m starting a new series of blogs posts on profiling, where we&amp;rsquo;ll try and cover common bottlenecks and how to identify them in your applications. However, before delving deeper into the subject, let me make a small but important observation:&lt;/p&gt;
&lt;p align="center"&gt;&lt;i&gt;Your bottleneck is probably not your for loop&lt;/i&gt;&lt;/p&gt;
&lt;p align="left"&gt;Now, replace that &lt;i&gt;for loop &lt;/i&gt;with &lt;i&gt;switch statement&lt;/i&gt;, an older version of some outdated algorithm that you feel needs optimizing, or that retched collection of classes that would perform better if you were using an array to loop through them, and you&amp;rsquo;ll end up with the same observation.&lt;/p&gt;
&lt;h3&gt;Premature Optimization&lt;/h3&gt;
&lt;p align="left"&gt;When dealing with business applications, it is unusual for major performance problems to be pinpointed down to specific portions of code or a concrete implementation of an algorithm. Usually most of the issues are bottlenecks at the data level, network level or purely down to how a business decision is made. &lt;/p&gt;
&lt;p&gt;Whether we use an ORM or use SQL directly, incorrectly formulated queries are one of the most predominant causes of bad performance. Not understanding concepts such as Lazy or Eager loading when using an ORM can be disastrous to the performance of an application, and are usually portrayed as &amp;ldquo;ORM XYZ sucks at performance&amp;rdquo;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Network bandwidth and latency are other issues; when dealing with web applications for instance, having large pages (i.e. ViewState) or rendering Javascript directly without using script files, are a common problem for performance penalties. Making heavy calls to the server when very little information is required (i.e. UpdatePanel used incorrectly) are again main causes for concern. &lt;/p&gt;
&lt;p&gt;In many cases, design decisions we make early can affect the performance of our applications, and it is important to identify these concerns and address them correctly. Using an ORM, &lt;a href="http://nhprof.com"&gt;profiling it&lt;/a&gt;, understanding how Ajax really works and not worrying about &lt;a href="http://jquery.org"&gt;working with Javascript&lt;/a&gt;, or using an &lt;a href="http://nservicebus.com"&gt;asynchronous architecture&lt;/a&gt; when dealing with long running business processes are many ways to avoid bad performance in the long run. &lt;/p&gt;
&lt;p&gt;On the other hand, what we shouldn&amp;rsquo;t do is focus on micro-optimizations, on trying to make the most efficient, yet completely undecipherable algorithm to calculate the probability of winning money when buying lottery tickets, when the underlying problem is a bottleneck caused by a bad query. This kind of approach is often referred to as Premature Optimization, and can be disastrous for a project. &lt;/p&gt;
&lt;h3&gt;When it does boil down to code&lt;/h3&gt;
&lt;p&gt;Having said all that, there are times when we need better performance after having eliminated all the obvious causes, and need to discover why something is not performing as well as it should be. Of course, these concerns are greater when the nature of our application demands highly optimized code. In these cases, it is crucial to understand how things work in order to solve the problem. As a old-school boy, before we had managed libraries and drag-n-drop, I&amp;rsquo;m also a firm believer that it is always important to understand how things work under the covers, even if it is to just improve one self&amp;#39;s knowledge. &lt;/p&gt;
&lt;p&gt;Therefore, in these series of blog posts about performance, I&amp;rsquo;m going to focus on the latter, examining the details of code and how some things can perform better than others. So given the disclaimer, let&amp;rsquo;s get down to business. &lt;/p&gt;
&lt;p&gt;In order to do performance tuning, you need to use a tool. Setting stopwatches doesn&amp;rsquo;t work, because as &lt;a href="http://www.devspace.com/"&gt;Christian Gross&lt;/a&gt; so rightly pointed out during one of his talks, and I semi-quote: &amp;lsquo;if you&amp;rsquo;re using a stopwatch, you think you know where the bottleneck is. Most of the time, you&amp;rsquo;re wrong&amp;rsquo;.&amp;nbsp; If you are setting using a manual approach of setting calling Start and Stop, trying to time something, you&amp;rsquo;re assuming you know that the performance problem is located in a particular point, and many times it is not that point. So you end up having to place these kind of diagnostic codes in various places in your code, and soon it becomes a maintenance nightmare. Fortunately, there are tools that can profile your application in a non-invasive manner. When talking about SQL profiling, there&amp;rsquo;s &lt;a href="http://nhprof.com"&gt;NHProfiler&lt;/a&gt; for instance. When it comes to code performance profiling, the two most known ones are &lt;a href="http://www.red-gate.com/products/index.htm"&gt;ANT Profiler&lt;/a&gt; and &lt;a href="http://www.jetbrains.com/dottrace"&gt;dotTrace&lt;/a&gt;. I&amp;rsquo;m going to be using dotTrace. I used it before joining &lt;a href="http://www.jetbrains.com"&gt;JetBrains&lt;/a&gt; and continue to use it now that I&amp;rsquo;m at JetBrains. I&amp;rsquo;ll be using &lt;a href="http://www.jetbrains.net/confluence/display/NetProf/4.0+Nightly+Builds"&gt;version 4.0&lt;/a&gt; which is currently (at the time of writing this post), in &lt;a href="http://www.jetbrains.net/confluence/display/NetProf/4.0+Nightly+Builds"&gt;Early Access Program&lt;/a&gt; and with Beta being released very soon. &lt;/p&gt;
&lt;h3&gt;To Express or not Express&lt;/h3&gt;
&lt;p&gt;Those that are familiar with it ASP.NET MVC know it relies heavily on the use of strings in many areas. For instance, when defining ActionLinks, you write&lt;/p&gt;
&lt;p align="center"&gt;Html.ActionLink(&amp;ldquo;Home&amp;rdquo;, &amp;ldquo;Index&amp;rdquo;, &amp;ldquo;Home&amp;rdquo;)&lt;/p&gt;
&lt;p align="left"&gt;where the first parameter is the link text, the second the Action and the third parameter is the Controller. The problem with this of course is that if you type either the second or third parameter incorrectly, you won&amp;rsquo;t know until runtime. Even if you build your views it won&amp;rsquo;t help. &lt;/p&gt;
&lt;p align="left"&gt;An alternative is to use Expression based Html Helpers (&lt;a href="http://hadihariri.com/blogengine/post/2010/01/20/ASPNET-Support-in-ReSharper-5.aspx"&gt;another option&lt;/a&gt; is to use &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; of course :)). These are strongly-typed ActionLinks that do not ship out of the box with ASP.NET MVC, but are available as a separate download in the &lt;a href="http://aspnet.codeplex.com/releases/view/39978"&gt;MVC Futures&lt;/a&gt; assembly, which can be thought of as a kind of sandbox for Microsoft to play with. Some of the functionalities in this library have eventually made it to the main core, such as &lt;i&gt;RenderPartial&lt;/i&gt;, which was in fact there from pretty much the early Previews of MVC 1, and didn&amp;rsquo;t get all the excitement until it made it into the core in version 2. Other functionality, including the expression based ActionLinks haven&amp;rsquo;t made it in yet. When using these helpers, the previous link would be: &lt;/p&gt;
&lt;p align="center"&gt;Html.ActionLink&amp;lt;HomeController&amp;gt;( a =&amp;gt; a.Index, &amp;ldquo;Home&amp;rdquo;)&lt;/p&gt;
&lt;p align="left"&gt;In principle this looks good, and begs the question of why it is not in the main core. Well I don&amp;rsquo;t know the exact reason, but one could potentially be due to it&amp;rsquo;s performance. Several people have talked about the difference in terms of rendering when using this version as opposed to the standard string based one. You can find one of those &lt;a href="http://codeclimber.net.nz/archive/2009/04/17/the-performances-implications-of-the-expression-tree-based-actionlink-helper.aspx"&gt;posts here&lt;/a&gt;. What I thought I&amp;rsquo;d do, is actually see how much difference in speed there is between one and the other. &lt;/p&gt;
&lt;h3&gt;The Project&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m using a very simple project for this profiling. It&amp;rsquo;s your standard ASP.NET MVC 2 application. On Index page, I&amp;rsquo;ve added two blocks of code:&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:23dd89a5-1ba6-4e74-9e95-9d4c09d76120" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#000000;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;for&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; (&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;int&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; i = &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;0&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i &amp;lt; &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;1000&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i++)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;= Html.ActionLink(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Link &amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; + i, &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;, &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;)&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#e8bc64;"&gt;br&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;}&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;for&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; (&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;int&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; i = &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;0&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i &amp;lt; &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;1000&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i++)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;= Html.ActionLink&amp;lt;&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HomeController&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;&amp;gt;(a =&amp;gt; a.Index(), &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Link &amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; + i)&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#e8bc64;"&gt;br&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;}&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="left"&gt;The first &lt;i&gt;for &lt;/i&gt;loop will render out 1000 links using the string based ActionLink version, whereas the second loop will do the same using the expression-based one. &lt;/p&gt;
&lt;p align="left"&gt;What we want to do now is run this and see how long it takes for each loop to complete. &lt;/p&gt;
&lt;h3&gt;Setting up dotTrace Profiler&lt;/h3&gt;
&lt;p&gt;Working with &lt;a href="http://www.jetbrains.com/dottrace"&gt;dotTrace&lt;/a&gt; is as easy as it gets. There are two ways to profile an application: Standalone or integrated within Visual Studio. In the case of the former, you can start up dotTrace outside of Visual Studio and point to an application to profile. On the other hand if you have it integrated inside Visual Studio, then all you need to do is click on the Profile menu option: &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_1B563413.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_4C093BBE.png" border="0" height="150" width="312" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Once we do that, we get a dialog box that provides us a series of options, mainly to do with the type of profiling we are going to perform. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_1E3B72F9.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_4358BD65.png" border="0" height="225" width="330" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Since we&amp;rsquo;re profiling a web application, we can either use the Development Server or Internet Information Server. In our case we&amp;rsquo;re going to use the former. dotTrace will automatically pick up the server settings as well as fill out the physical path for our application. &lt;/p&gt;
&lt;p&gt;Next come the profiling options. The basic settings are Profiling Type and Meter Kind. The first parameter indicates how profiling will take place. It can be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sampling: dotTrace will do frequent analysis of calls stacks. It&amp;rsquo;s the least intrusive, has very little impact on performance, but gives approximate timing. &lt;/li&gt;
&lt;li&gt;Tracing: dotTrace receives notifications from the CLR on entry/exit of methods. More precise timing and call information. &lt;/li&gt;
&lt;li&gt;Line-by-Line: dotTrace logs times for every statement in methods. Most precise but also has higher impact on performance. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tracing is normally the recommended option. Meter Kind defines how dotTrace logs the time: CPU instruction or Performance counter (uses the Windows API and samples are hardware independent). &lt;/p&gt;
&lt;h3&gt;Profiling our application&lt;/h3&gt;
&lt;p&gt;Once we have everything setup, we can start profiling our app. dotTrace will launch a small panel that allows us to control data sampling. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_19954272.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_45D1C956.png" border="0" height="194" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;dotTrace does not by default however launch the browser. In order to do so, we need to either click on the WebDev server and Open in Browser or just type the URL directly in the browser. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_2399BDD0.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_349DEBB3.png" border="0" height="103" width="193" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The next step is to perform the operations we want to profile and then click on GetSnapshot. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_45A21996.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_51C393BD.png" border="0" height="268" width="372" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Since in our case, having rendered the &lt;i&gt;Index &lt;/i&gt;action performs these operations, once the page has been loaded, we can click on GetSnapshot and have the profiler launched. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_2F8B8837.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_08AD4C2A.png" border="0" height="293" width="430" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going to get into all of the details of dotTrace in this first post because otherwise it would never end;&amp;nbsp; we&amp;rsquo;ll cover some of the aspects in future posts. For now, lets focus on our performance test at hand which is the difference between the two types of ActionLinks (string and expression based). &lt;/p&gt;
&lt;p&gt;The easiest way to find what we are looking for is to use the&amp;hellip;you guessed it, Find feature. Ctrl+F will bring up a dialog box similar to ReSharper&amp;rsquo;s Type location. We can then type ActionLink to filter the list of functions down to the ones that interest us&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_248E5B55.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_54D5300B.png" border="0" height="83" width="467" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;We can see that there are two versions, as expected. Let&amp;rsquo;s drill in to the second one first, the string based one. Hitting Enter will find the first location. We can then press F3 until we find the one that interests us. Remember, Site.Master and other references to this call also exist. We&amp;rsquo;re specifically looking for the loop, the one with 1000 calls&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_39502E08.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_00955E2E.png" border="0" height="171" width="546" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;We can see that the &lt;i&gt;ActionLink&lt;/i&gt; call takes 121ms for 1000 calls. Drilling in, we can see exactly where the time is spent, and 104ms of that is calling &lt;i&gt;GenerateUrl&lt;/i&gt;. Now let&amp;rsquo;s take a look at the Expression based ActionLink&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_45BD8F8A.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_56B197A0.png" border="0" height="116" width="542" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;For the same 1000 calls it takes 140ms, which is an increase of approximately 17%. Diving in once again, we can see that 6ms of this is in the parsing of the expression tree, &lt;i&gt;GetRouteValuesFromExpression. &lt;/i&gt;What this function does is merely analyze the expression to extract the ActionName from the parameter. The ControllerName it already has since it&amp;rsquo;s the concrete type the generic method is invoked with, returning both values in a &lt;i&gt;RouteValueDictionary&lt;/i&gt;. As such it then needs to call &lt;i&gt;GenerateRouteLink &lt;/i&gt;as opposed to &lt;i&gt;GenerateLink &lt;/i&gt;since the former takes a &lt;i&gt;RouteValueDictionary &lt;/i&gt;as a parameter, whereas the latter takes strings indicating the controller and action. They ultimately both call &lt;i&gt;GenerateUrl&lt;/i&gt;. &lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;From the results, the difference between the two calls is not that significant for 1000 links. As the number of links increment, the difference between the two does not change significantly. For instance, rendering 10.000 links, has a difference of 50ms between one version and another. What&amp;rsquo;s interesting that having run the same profiling on previous
releases, the difference in time was nearly double, so there seems to
have been improvement in this area. And as we can see, sometimes what might seem a performance problem, isn&amp;#39;t necessarily one.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55802" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/pIzK9mwB1vY" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Profiling/default.aspx">Profiling</category><feedburner:origLink>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/09/profiling-apps-1-of-n-the-mvc-actionlink.aspx</feedburner:origLink></item><item><title>Rule "Previous releases of Microsoft Visual Studio 2008" failed</title><link>http://feedproxy.google.com/~r/Devlicious/~3/U2fHsOZim80/rule-quot-previous-releases-of-microsoft-visual-studio-2008-quot-failed.aspx</link><pubDate>Sun, 07 Mar 2010 10:43:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55695</guid><dc:creator>sergiopereira</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;
 Today I was trying to install SQL 2008 on my box and the setup stopped after checking a bunch of
rules. The error message was the title of this post.
&lt;/p&gt;

&lt;p&gt;
A quick search on the internet revealed that somehow the installer didn&amp;#39;t believe I had VS 2008 &lt;b&gt;SP1&lt;/b&gt;
installed, which I did. The recommendations in &lt;a href="http://support.microsoft.com/kb/956139"&gt;the KB article&lt;/a&gt;
were kind of insulting. There&amp;#39;s no way I&amp;#39;d spend hours of my day uninstalling and reinstalling VS and SQL &amp;mdash; sorry, no chance. I
also could not accept not installing the Management Tools, for example. I also did not have any Express version of VS or SQL installed in this box.
&lt;/p&gt;

&lt;p&gt;
A little snooping around with &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx"&gt;ProcMon&lt;/a&gt;
led me to the following registry key: 
&lt;/p&gt;

&lt;pre&gt;HKLM\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS\Servicing\9.0\IDE\1033&lt;/pre&gt;

&lt;p&gt;
In that key I noticed the suspicious values:
&lt;/p&gt;

&lt;pre&gt;&amp;quot;SP&amp;quot;=dword:00000000
&amp;quot;SPIndex&amp;quot;=dword:00000000
&amp;quot;SPName&amp;quot;=&amp;quot;RTM&amp;quot;
&lt;/pre&gt;

&lt;p&gt;
Without quitting the SQL server installer validaton screen, I changed these values to what you see below, crossed my fingers 
and rerun the installer validation, &lt;b&gt;which passed!&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;&amp;quot;SP&amp;quot;=dword:00000001
&amp;quot;SPIndex&amp;quot;=dword:00000001
&amp;quot;SPName&amp;quot;=&amp;quot;SP1&amp;quot;
&lt;/pre&gt;

&lt;p&gt;
Now, I didn&amp;#39;t really guess those values. I looked in a sibling registry key (...Servicing\9.0\IDE\1033) and saw
that it contained those new values, then I copied them. 
&lt;/p&gt;

&lt;p&gt;
I think I didn&amp;#39;t break anything. So far all seems to be working. But, as usual with anything related
to manual registry hacking, you have to be really insane to change your settings because you
read on a random blog on the &amp;#39;net. I&amp;#39;m just saying... Don&amp;#39;t come crying if your house burns down because of this.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55695" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/U2fHsOZim80" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/SQLServer/default.aspx">SQLServer</category><feedburner:origLink>http://devlicio.us/blogs/sergio_pereira/archive/2010/03/07/rule-quot-previous-releases-of-microsoft-visual-studio-2008-quot-failed.aspx</feedburner:origLink></item><item><title>The Biggest Driver For Domain Modeling Decisions</title><link>http://feedproxy.google.com/~r/Devlicious/~3/guBJtmxGaQ4/the-biggest-driver-for-domain-modeling-decisions.aspx</link><pubDate>Sun, 07 Mar 2010 06:45:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55700</guid><dc:creator>Michael Nichols</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;I just read a &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/06/a-few-thoughts-on-ddd-dtos-view-models-cqs-repositories-and-separation-of-concerns.aspx" target="_blank"&gt;post&lt;/a&gt; from fellow devlicio.us&amp;#39;er &lt;a href="http://devlicio.us/blogs/billy_mccafferty/default.aspx" target="_blank"&gt;Billy McCafferty&lt;/a&gt; and was considering what influences my own solutions to these concerns (ie, repositories, data transfer, etc) now. &lt;/p&gt;
&lt;p&gt;There has been an abrupt shift/growth in my thinking this year in how I perceive my domain and how I interact with or scale it. CQRS, perceived by some as a shiny new toy, and the discussions it provokes has definitely contributed to the maturity of the project I have been on by increasing its quality and adaptability. Why? My experience has been the simple shift to being concerned about what all these things are &lt;i&gt;doing&lt;/i&gt; (behavioral mindset) instead of what they &lt;i&gt;look like&lt;/i&gt; (stateful mindset). I now see that the decision to expose domain state &lt;i&gt;at all &lt;/i&gt;should be one of the first decisions to make and its implications on the various infrastructural concerns should be well-understood. This seems to drive divers decisions both within the domain and how it is consumed or utilized without. &lt;/p&gt;
&lt;p&gt;The first casualty of this shift was the getters and setters (whether exposed as properties or GetX()/SetX() methods). Hiding as much state as possible radically increases the freedom in the domain, especially when going down the &lt;a href="http://martinfowler.com/eaaDev/EventSourcing.html" target="_blank"&gt;event-sourcing&lt;/a&gt; route. As you know, the moment you expose a getter you now have a maintenance obligation. What I am discovering is that feels okay initially, but it very quickly acts as a Trojan Horse for forces outside the domain to act on its modeling. That innocent {get;} can make refactoring far more difficult that it needs to be, if only the decision were made earlier to Report state from somewhere other than the domain. &lt;/p&gt;
&lt;p&gt;IMHO, this is true for a &amp;ldquo;small&amp;rdquo; application, although I am not sure I believe in &amp;ldquo;small&amp;rdquo; applications anymore. They all seem to be getting feature-creep hormones from somewhere :). &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55700" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/guBJtmxGaQ4" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/mike_nichols/archive/tags/Domain+Driven+Design+_2800_DDD_2900_/default.aspx">Domain Driven Design (DDD)</category><category domain="http://devlicio.us/blogs/mike_nichols/archive/tags/Project+Structure/default.aspx">Project Structure</category><category domain="http://devlicio.us/blogs/mike_nichols/archive/tags/CQRS/default.aspx">CQRS</category><feedburner:origLink>http://devlicio.us/blogs/mike_nichols/archive/2010/03/06/the-biggest-driver-for-domain-modeling-decisions.aspx</feedburner:origLink></item><item><title>Providing Metadata to your MEF exports</title><link>http://feedproxy.google.com/~r/Devlicious/~3/Qsgx_hJHftY/providing-metadata-to-you-mef-exports.aspx</link><pubDate>Sun, 07 Mar 2010 01:07:24 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55689</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>4</slash:comments><description>&lt;p&gt;Many months ago I created a post on how to get started with &lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2009/10/27/simple-kick-start-example-using-mef-preview-8.aspx"&gt;MEF&lt;/a&gt;.&amp;#160; Ever since then I have been meaning to get this post (and others) about about how to get up and running quickly with MEF.&lt;/p&gt;  &lt;p&gt;In this post will demonstrate how to provide Metadata (custom values which can help provide context) information to your Exported item.&amp;#160; Why should you care about Metedata?&amp;#160; Below is a great reason from the MEF site on codeplex&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://mef.codeplex.com/wikipage?title=Declaring%20Exports&amp;amp;referringTitle=Exports%20and%20Metadata"&gt;Declaring Exports&lt;/a&gt; explained the basics of parts exporting services and values. In some cases it’s necessary to associate information with exports for a variety of reasons. Commonly it’s used to explain about the capabilities of an specific implementation of a common contract. This is useful to allow imports to either constraint the export that can satisfy it, or to import all available implementations at the time and check their capabilities in runtime before using the export.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Before we get rolling:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;What I am going to show in this post is how to create a custom Export Attribute.&amp;#160; It is possible to expose Meta via the build in ExportAttribute, but the built in mechanism has a few short comings:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Not discoverable &lt;/li&gt;    &lt;li&gt;Not strongly typed &lt;/li&gt;    &lt;li&gt;Compiler cannot validate the data content &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Lets get rolling:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Pre-Step 1: Taking a look at the Class which we will mark as a Export&lt;/strong&gt;&lt;/p&gt;  &lt;pre class="c-sharp" name="code"&gt;    public interface IPlugin
    {
        string PluginAction();
    }

    [Export(typeof(IPlugin))]
    public class DefaultPlugin : IPlugin 
    {
        public string PluginAction()
        {
            return &amp;quot;This is the default plugin&amp;quot;;
        }
    }&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Defining the interface which will represent your&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to create discoverable Metadata you will first want to create an interface which will represent your metadata.&amp;#160; Below is my interface.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;    public interface IPluginMetaData
    {
        string Name { get; }
        string Version { get; } 
    }&lt;/pre&gt;

&lt;p&gt;We will later use this interface when we define and use our custom Export Attribute.&amp;#160; The main reason for creating this attribute is now the compiler has a hard wired way to know exactly what type of data is being exposed in your Metadaa&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Defining your custom ExportAttribute Attribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we created our interface to give us strong typing and discoverability we need to create a custom attribute which will allows the MEF engine to know we have Metadata to expose&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class PluginMetadataAttribute : ExportAttribute
    {
        public PluginMetadataAttribute( string name, string version)
            : base(typeof(IPluginMetaData))
        {
            Name = name;
            Version = version;
        }

        public string Name { get; set; }
        public string Version { get; set; }
    }&lt;/pre&gt;

&lt;p&gt;When looking at the code above there are 3 things to pay close attention to&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You need to make a call into the base constructor of the ExportAttribute and provide it the type of your interface which defines your Metadata &lt;/li&gt;

  &lt;li&gt;You need to mark your attribute with the [MetadataAttribute] (which is part of MEF) &lt;/li&gt;

  &lt;li&gt;You need to mark the usage type of your attribute.&amp;#160; I am not 100% why this is needed (Glenn, you out there with an answer???) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Providing your Metdata to your Exported Class&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;    [Export(typeof(IPlugin))]
    [PluginMetadata(&amp;quot;Default&amp;quot;, &amp;quot;1.0.0.0&amp;quot;)]
    public class DefaultPlugin : IPlugin 
    {
        public string PluginAction()
        {
            return &amp;quot;This is the default plugin&amp;quot;;
        }
    }&lt;/pre&gt;

&lt;p&gt;The code above is the same as the code we saw in pre-step 1, but this time we have marked the class with our custom Metadata attribute.&amp;#160; We have now officially provided our Metadata to our Export…. But how do we get this information out of MEF?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Setting up your [ImportMany] to use the Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are using an ImportMany (this should also work on an Import, but I have never tried) most likely you are pushing your Exports into a IList or IEnumerable.&amp;#160; If this is the case, your changes are pretty minor.&amp;#160; Below is what you need to do in order to have your Metadata loaded.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;[ImportMany(typeof(IPlugin), AllowRecomposition = true)]
private IList&amp;lt;Lazy&amp;lt;IPlugin, IPluginMetaData&amp;gt;&amp;gt; _loadedIPlugins = new List&amp;lt;Lazy&amp;lt;IPlugin, IPluginMetaData&amp;gt;&amp;gt;();&lt;/pre&gt;

&lt;p&gt;If you have not seen the &lt;a href="http://msdn.microsoft.com/en-us/library/dd642331%28VS.96%29.aspx"&gt;Lazy&lt;/a&gt; keyword, you are not alone.&amp;#160; This is new to .Net 4 and this provides Lazy initialization support to the framework.&amp;#160; (part of the System namespace).&amp;#160; One key thing to understand here though is that the Lazy keyword out the box is only Lazy&amp;lt;T&amp;gt;, but the Lazy we are using is Lazy&amp;lt;T, M&amp;gt;.&amp;#160; This extended version of Lazy lives in the MEF assemblies (System.ComponentModel.Composition) and will need to be referenced to use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Using the Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you have the Export loaded into your container (which by the way does not need to change to have this work) you can access your container by selecting the .Metadata property on your instance of the export.&amp;#160; The image below shows it in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_0421BA20.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/derik_5F00_whittaker/image_5F00_thumb_5F00_639A7A6D.png" width="180" height="151" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, exposing and using Metadata via MEF is a snap.&amp;#160; &lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55689" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/Qsgx_hJHftY" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/MEF/default.aspx">MEF</category><feedburner:origLink>http://devlicio.us/blogs/derik_whittaker/archive/2010/03/06/providing-metadata-to-you-mef-exports.aspx</feedburner:origLink></item><item><title>A Few Thoughts on DDD, DTOs, View Models, Repositories and Separation of Concerns</title><link>http://feedproxy.google.com/~r/Devlicious/~3/b2zdkd_lX40/a-few-thoughts-on-ddd-dtos-view-models-cqs-repositories-and-separation-of-concerns.aspx</link><pubDate>Sat, 06 Mar 2010 16:41:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55672</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>13</slash:comments><description>&lt;p&gt;What I&amp;#39;ve loved most about developing an open-source project is the ideas that I get from others who look at the work and either A) validate ideas, B) suggest that something stinks, or C) call a royal WTF and force people (e.g., me) &amp;nbsp;to explain ideas more fully. &amp;nbsp;It&amp;#39;s usually during these explanation attempts that light bulbs start to come on and ideas are refactored and become more substantiated (or at least more defendable). &amp;nbsp;The S#arp Architecture forums have been a gold mine, IMO, for the discussion of the practical application of balanced DDD techniques on real-world projects. &amp;nbsp;After feedback that I&amp;#39;ve already gotten on my recent &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx"&gt;post concerning application services and CQS&lt;/a&gt;&amp;nbsp;and listening to and adding my two cents concerning ideas on the S#arp forums, I&amp;#39;d like to share a few ideas (that I shared on the forum) concerning drawing the line among application layers, the management of DTOs and View Models, and a general discussion of separation of concerns. &amp;nbsp;(As &lt;a href="http://panteravb.com/blog/posts/2009/1/9/because-thats-how-they-do-it-in-sharp-architecture.ashx"&gt;Chris Carter correctly (and a tad bluntly) explained&lt;/a&gt;, don&amp;#39;t take these ideas at face value...use them as a point of discussion and contemplation to come to your own conclusions with your project team...and let me know what you think.)&lt;/p&gt;
&lt;p&gt;Every great developer knows that any problem can be solved by adding another layer of abstraction. &amp;nbsp;;)&lt;/p&gt;
&lt;p&gt;Obviously, with additional layers of abstraction and indirection, we also introduce complexity and additional objects which need to be maintained. &amp;nbsp;Over the past year, I have had struggles concerning just how far the &amp;quot;DTO paradigm&amp;quot; should be taken to effectively separate layers from the domain and &amp;quot;best practices&amp;quot; for how they should be used. &amp;nbsp;I don&amp;#39;t think the answer can be found in a best practice (but I also hate to leave it simply at &amp;quot;it depends&amp;quot;). &amp;nbsp;I truly feel that the most important practice is for a project development team to decide, and firmly agree upon, which approach will be taken on a project and for the agreed upon approach to be followed with discipline (and enforced via code reviews) by the team.&lt;/p&gt;
&lt;p&gt;On a couple of recent projects, the biggest problems we ran into weren&amp;#39;t concerning &lt;i&gt;which&lt;/i&gt;&amp;nbsp;approach to leveraging DTO for layer separation was &amp;quot;best,&amp;quot; but on coming to a firm layering decision and having the team discipline to adhere to those practices. &amp;nbsp;Because of these &amp;quot;gray&amp;quot; areas, which we didn&amp;#39;t come to a firm team agreement on, there were inconsistent practices used by the developers which led to rot, particularly between the controller (or code-behind) and application services layer.&lt;/p&gt;
&lt;p&gt;So while we can discuss which approach is best or most effective, I think the greater concern is for the team to pick a direction, to stick to it, and to diverge or refactor as a team decision.&lt;/p&gt;
&lt;p&gt;But as I said, I don&amp;#39;t want to leave it at &amp;quot;it depends.&amp;quot; ;) &amp;nbsp;So after reading everyone&amp;#39;s ideas here and contemplating further on past projects and the ideas I recently put forth in &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx"&gt;http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx&lt;/a&gt;, here are a couple of ideas that I&amp;#39;ve been trying to adhere to (and/or will be adhering to on my next project). &amp;nbsp;The layers referenced below may be viewed in a &lt;a href="http://github.com/codai/Sharp-Architecture/raw/master/docs/ProjectArchitecture.PNG"&gt;package diagram here&lt;/a&gt;&amp;nbsp;for better clarity of what&amp;#39;s discussed.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usually, one object should be used to populate a form while a second should be used to collect data from a form. &amp;nbsp;The former would contain information for&amp;nbsp;default/selected values along with&amp;nbsp;drop-down values, for examples, while the latter would encapsulate which options were selected when the user submitted the form. &amp;nbsp;Personally, I use a &amp;lt;EnityName&amp;gt;FormViewModel to populate the form and use an entity to collect from the form...but I see it equally valid to instead use an intermediary DTO to collect from the form if further separation is warranted. &amp;nbsp;Additionally, I feel it is OK for a FormViewModel object to have references to domain objects to make it easier to transfer data to the form for input population. &amp;nbsp;This is an arguable point and would be just as valid to only pass DTOs in the view model for a cleaner separation between view and domain, with the acceptance that there will be more objects and maintenance that comes with that approach.&lt;/li&gt;
&lt;li&gt;I believe that view models should be maintained either in the application services layer OR in a separate ViewModels class library if a project team feels the additional separation is warranted (although I can&amp;#39;t envision much reason to do so). &amp;nbsp;(I&amp;#39;ll be modifying my sample project post to reflect the former.) &amp;nbsp;Either way, they should not be maintained in .Core to keep a very clean separation from domain concerns. &amp;nbsp;While the name &amp;quot;ViewModel&amp;quot; implies that they are a view concern, they only describe &lt;i&gt;what&lt;/i&gt;&amp;nbsp;should be displayed, not &lt;i&gt;how&lt;/i&gt; it should be displayed. &amp;nbsp;Accordingly, there is still a very clear separation of concerns between the view layer (which the user interacts with) and the view model classes. &amp;nbsp;Furthermore, the application services expose methods which should be usable by any type of client. &amp;nbsp;In line with this, a ViewModel or FormViewModel class does not impart a particular mechanism for the implementation of the view layer - again, it only describes &lt;i&gt;what&lt;/i&gt;&amp;nbsp;data should be available to the view. &amp;nbsp;So even if view model classes are maintained in app services, this does not preclude there use by various client types; e.g., they could be equally consumed by ASP.NET, ASP.NET MVC, Spark, SilverLight, etc. &amp;nbsp;(The only caveat is that if the view model classes maintain references to domain objects, then it will be more difficult to expose them for serialization via web services and WCF. Accordingly, a project team should firmly decide if ViewModels may contain references to domain objects.)&lt;/li&gt;
&lt;li&gt;I believe that DTOs should be maintained in a separate assembly and have no reference to .Core or be maintained in .Core if warranted with the acceptance of decreased &amp;quot;shareability.&amp;quot; &amp;nbsp;DTOs should almost always be serializable; i.e., transferable via web services and WCF. &amp;nbsp;This allows the DTOs class library to be easily shared with a consumer of web services which may expose these objects, for easier deserialization. &amp;nbsp;Some of the motivations for deciding when to use DTOs would be to provide a clean separation between the view and app services (if a project team feels its warranted), to expose data to web service consumers, and to better enable Command/Query Separation.&lt;/li&gt;
&lt;li&gt;Repositories may return Entities, Value Objects or DTOs, in addition to other &amp;quot;basic&amp;quot; types; e.g., primitives, arrays, etc. &amp;nbsp;Ideally, repositories would not be used by domain objects (even via their interfaces) and would have their interfaces maintained in the application services layer. &amp;nbsp;If the repository interfaces are maintained in .Core, then this forces DTOs to be maintained in .Core as well with the possibility that domain references may &amp;quot;leak&amp;quot; into DTOs. &amp;nbsp;If the repository interfaces are maintained in .ApplicationServices, then DTOs may be maintained in a cleanly separated library without worrying about the line between DTOs and domain objects being grayed. &amp;nbsp;But data interfaces (and DTOs) may be maintained in .Core if the team feels the simplification is warranted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With all this said, I still think the most important decision is deciding a path to take for your project, having the project team agree upon it, and maintaining the discipline to stay on course.&lt;/p&gt;
&lt;p&gt;Your feedback on these ideas is most welcome!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55672" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/b2zdkd_lX40" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DeepThoughtsByJackHandey/default.aspx">DeepThoughtsByJackHandey</category><feedburner:origLink>http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/06/a-few-thoughts-on-ddd-dtos-view-models-cqs-repositories-and-separation-of-concerns.aspx</feedburner:origLink></item><item><title>Better Application Services and CQS using S#arp Architecture 1.0 Q3 2009</title><link>http://feedproxy.google.com/~r/Devlicious/~3/DglNLm9GPjQ/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx</link><pubDate>Fri, 05 Mar 2010 18:47:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55653</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>4</slash:comments><description>&lt;p&gt;&lt;i&gt;Updated 2010.03.09 to reflect small modifications that were decided through subsequent discussions on S#arp forum and other DDD posts.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Obviously, &lt;a href="http://wiki.sharparchitecture.net/"&gt;S#arp Architecture&lt;/a&gt; is the bee&amp;#39;s knees when it comes to developing ASP.NET MVC applications. ;) &amp;nbsp;But as a project evolves and gets larger, &amp;quot;out of the box&amp;quot; S#arp Architecture 1.0 guidance runs into a few pain points. &amp;nbsp;Particularly, there&amp;#39;s poor use of the &lt;a href="http://martinfowler.com/eaaCatalog/serviceLayer.html"&gt;application services&lt;/a&gt; layer, the separation between controllers and application services is not very clear, entity listing pages become performance bottlenecks as the domain model gets sizable, there is no &lt;a href="http://devlicio.us/blogs/casey/archive/2009/02/12/ddd-command-query-separation-as-an-architectural-concept.aspx"&gt;command/query separation (CQS)&lt;/a&gt;&amp;nbsp;&amp;quot;out of the box&amp;quot;, and unit tests require re-occurring&amp;nbsp;maintenance to deal with changes in the number of constructor parameters to controllers and application services. &amp;nbsp;While the amicable and adroit&amp;nbsp;&lt;a href="http://weblogs.asp.net/alecwhittington/default.aspx"&gt;Alec Whittington&lt;/a&gt;&amp;nbsp;(who is taking over the lead role from me on S#arp Architecture) is hard at work upgrading S#arp Architecture to accommodate recent dependency upgrades and accommodating ASP.NET MVC 2, I wanted to take a stab at resolving some of the architectural issues that I&amp;#39;ve run into, on S#arp projects over the past year.&lt;/p&gt;
&lt;p&gt;
        I&amp;#39;ve developed and included a sample project, built on S#arp Architecture 1.0 Q3 2009, for the following key reasons:
        &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To resolve some &amp;quot;pain points&amp;quot; that develop as S#arp projects grow to large sizes,&lt;/li&gt;
&lt;li&gt;To demonstrate better use of the application services layer,&lt;/li&gt;
&lt;li&gt;To demonstrate better command/query separation of the entity listing pages for dramatically 
            better performance as the domain model grows,&lt;/li&gt;
&lt;li&gt;To create an architectural spike for a new project I&amp;#39;m working on, and&lt;/li&gt;
&lt;li&gt;To collect feedback from the S#arp community to determine if this is an 
            appropriate architectural direction for the next release of S#arp Architecture.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
        Please post any feedback and/or suggestions you may have in the comments below or, more preferably, to the S#arp Architecture forums at 
        &lt;a href="http://groups.google.com/group/sharp-architecture"&gt;http://groups.google.com/group/sharp-architecture&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Setup instructions&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Unzip the sample project to a BetterAppServices folder&lt;/li&gt;
&lt;li&gt;Create a new database called BetterAppServices&lt;/li&gt;
&lt;li&gt;Using SQL Enterprise Manager, run:
	&lt;ol&gt;
&lt;li&gt;/BetterAppServices/db/Schema/CreateBetterAppServicesDb_ChangesWillBeLost.sql&lt;/li&gt;
&lt;li&gt;/BetterAppServices/db/StoredProcedures/CreateGetProductCategorySummaries.sql&lt;/li&gt;
&lt;li&gt;/BetterAppServices/db/StoredProcedures/CreateGetProductSummaries.sql&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Open /BetterAppServices/BetterAppServices.sln with VS 2008&lt;/li&gt;
&lt;li&gt;In VS 2008, open BetterAppServices.Web/NHibernate.config and change the connection string to point to your BetterAppServices database&lt;/li&gt;
&lt;li&gt;Right click the BetterAppServices.Web project and &amp;quot;Set as StartUp Project&amp;quot;&lt;/li&gt;
&lt;li&gt;Run (F5) the project to see everything in action.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Changes from &amp;quot;out of the box&amp;quot; S#arp Architecture 1.0 Projects&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
        This project is more of an architectural spike more than anything else at the moment.  
        Accordingly, the CRUD scaffolding generator has been removed and non-essential unit tests 
        have been removed to focus on the architecture itself. &amp;nbsp;Many of the changes will be 
        incorporated into the S#arp CRUD scaffolding generator; this will either be available in the next
        release, or will be provided as an add-on, as this new approach &lt;i&gt;does&lt;/i&gt; add complexity and 
        introduces a major breaking change to existing 1.0 projects.
    &lt;/p&gt;
&lt;p&gt;
        Major changes include:
        &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
                /db Folder Changes
                
&lt;ul&gt;
&lt;li&gt;Added /db/Schema/CreateBetterAppServicesDb_ChangesWillBeLost.sql.  
                    This gets auto-regenerated when unit tests are run.  The motivation was to have the DB 
                    schema automatically maintained while developing.&lt;/li&gt;
&lt;li&gt;Added /db/StoredProcedures/CreateGet&lt;i&gt;EntityNamePlural&lt;/i&gt;Summaries.sql.  These SPs provide 
                    command/query separation for the entity listing (Index.aspx) pages, which frequently became a 
                    performance bottleneck.
                    &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                Cross-Project Changes
                
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;Moved /BetterAppServices.Core/DataInterfaces/* to /BetterAppServices.ApplicationServices/DataInterfaces/.  
                    &lt;strong&gt;This is the only major, possible breaking change for existing applications.&lt;/strong&gt;  This was done to further 
                    remove the potential of domain objects using data repositories directly, and to allow the repositories 
                    to return objects from a new Dtos project for command/query separation, among other benefits (dicussed below).&lt;/span&gt;&amp;nbsp;&amp;nbsp;Decided not to do this to support domain services which may require the use of repositories and to make upgrading from previous version much simpler in some cases. &amp;nbsp;Having the interfaces in .Core doesn&amp;#39;t necessitate that domain objects use them; in fact, my rule of thumb is for all domain objects to avoid the use of repositories unless an exceptive case exists.&lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;Replaced all uses of &amp;quot;using BetterAppServices.Core.DataInterfaces;&amp;quot; to 
                    &amp;quot;using BetterAppServices.ApplicationServices.DataInterfaces;&amp;quot; to support the above mentioned change.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Replaced all uses of IRepository&lt;i&gt;EntityName&lt;/i&gt; with I&lt;i&gt;EntityName&lt;/i&gt;Repository.  Be default, all 
                    entities now have an explicit repository.  This avoids the need to manually change from the generic to 
                    the explicit, when the need arose, in unit tests and in constructors; which was frequently occurring.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Core/QueryDtos (/BetterAppServices.Dtos)
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;Added a Dtos class library to provide an appropriate location for View Models and DTOs.  While this project 
                    currently has a dependency on BetterAppServices.Core, so that the View Models can contain references to 
                    domain objects, this dependency could be severed for better separation between the view and the domain. 
                    The caveat is that much more work would be required maintaining a more complete DTO layer and transferring 
                    data via DTOs in all of the CRUD pages.&lt;/span&gt;&amp;nbsp;&amp;nbsp;Decided that a separate assembly was overkill. &amp;nbsp;Consequently, added this namespace to contain query DTOs for transferring results of &amp;quot;report&amp;quot; queries into objects. &amp;nbsp;With this example project, only the listing page uses &amp;quot;pure&amp;quot; DTOs 
                    for much better performance.  The other CRUD pages still communicate directly with domain objects to keep 
                    things much simpler. This is something that can be argued either way and it should depend on the 
                    project needs to determine if a more separated approach is warranted.&lt;/li&gt;
&lt;li&gt;Added&amp;nbsp;&lt;i&gt;EntityName&lt;/i&gt;Dto.cs to act as a summary object to be bound to results from stored procedures (e.g., the entity listing pages), or other DTO needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;/BetterAppServices.ApplicationServices/ViewModels&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Added this namespace and&amp;nbsp;&lt;i&gt;EntityName&lt;/i&gt;FormViewModel.cs to hold data related to adding and updating the &lt;i&gt;EntityName&lt;/i&gt;.  
                    This object gets populated and passed to the entity form pages, accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.ApplicationServices
                
&lt;ul&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos so that app services can return DTOs.&lt;/li&gt;
&lt;li&gt;Added &lt;i&gt;EntityName&lt;/i&gt;ManagementService.cs.  This app service class removes the CRUD logic 
                    from the controllers, makes the logic more reusable, and creates an appropriate class to add 
                    additional application service logic to.&lt;/li&gt;
&lt;li&gt;Added I&lt;i&gt;EntityName&lt;/i&gt;ManagementService.cs.  This app service interface makes unit testing more 
                    maintainable because you can mock the service interface and not worry about when the concrete class&amp;#39; 
                    constructor arguments change.&lt;/li&gt;
&lt;li&gt;Added /DataInterfaces/I&lt;i&gt;EntityName&lt;/i&gt;Repository.cs.  As described above, every entity now has 
                    an explicit repository interface to avoid changes down the road when custom interfaces would inevitably 
                    be introduced.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Data
                
&lt;ul&gt;
&lt;li&gt;Added /BetterAppServices.Data/&lt;i&gt;EntityName&lt;/i&gt;Repository.cs to implement the associated interface. 
                    An important thing to note is that method provided invokes a stored procedure to act as a reporting means in 
                    line with command/query separation.  This is useful for entity listing pages which would frequently, previously, 
                    end up loading a huge portion of the domain model to show summary information.&lt;/li&gt;
&lt;li&gt;Added /BetterAppServices.Data/NamedQuery/Get&lt;i&gt;EntityName&lt;/i&gt;Summaries.hbm.xml and set its compile action to 
                    &amp;quot;Embedded Resource.&amp;quot;  This provides the &amp;quot;short cut&amp;quot; for invoking the stored procedure.  It could easily be modified 
                    to accept paging parameters.&lt;/li&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos so that repositories can return DTOs for better command/query 
                    separation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Web
                
&lt;ul&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos to be able show DTOs on web pages.&lt;/li&gt;
&lt;li&gt;Changed ComponentRegistrar.AddCustomRepositoriesTo &amp;quot;BetterAppServices.Core&amp;quot; to 
                    &amp;quot;BetterAppServices.ApplicationServices&amp;quot; to reflect the new location of the data repository interfaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Web.Controllers
                
&lt;ul&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Tests
                
&lt;ul&gt;
&lt;li&gt;Modified MappingIntegrationTests.CanGenerateDatabaseSchema to save DB schema to 
                    /db/Schema/CreateBetterAppServicesDb_ChangesWillBeLost.sql every time the unit test is run.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
        
        To reiterate, many of the changes above can be incorporated into a CRUD scaffolding generator; the focus with this example 
        project is on providing an archtectural spike of the proposed architectural revisions.&lt;/p&gt;
&lt;p&gt;Even if you don&amp;#39;t use S#arp Archtiecture, this sample project should serve as a good example of using application services and basic use of command/query separation (CQS). &amp;nbsp;Although the CQS in the sample project could be taken much further, I felt that the sample provides a good balance between practical maintainability and a more austere separation of concerns.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55653" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/DglNLm9GPjQ" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Architecture/default.aspx">S#arp Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category><feedburner:origLink>http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/Devlicious/~5/kFt3ArAhdGU/BetterAppServices.rar" length="2841490" type="application/octet-stream" /><feedburner:origEnclosureLink>http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.05.56.53/BetterAppServices.rar</feedburner:origEnclosureLink></item><item><title>1 Simple Step for Commanding in Silverlight</title><link>http://feedproxy.google.com/~r/Devlicious/~3/V19lz9-PRfM/1-simple-step-for-commanding-in-silverlight.aspx</link><pubDate>Wed, 03 Mar 2010 16:24:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55619</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;Silverlight 4 is now supporting the commanding that we’ve come to love from WPF. Commanding was a foundational feature for MVVM. It’s what enabled us to bind to methods on our view models.&lt;/p&gt;  &lt;p&gt;John Papa has an excellent introductory post on &lt;a href="http://johnpapa.net/silverlight/5-simple-steps-to-commanding-in-silverlight"&gt;using commands in Silverlight 4&lt;/a&gt;. This pattern is called the DelegatingCommand pattern (or sometimes RelayingCommand). &lt;/p&gt;  &lt;p&gt;I’d like to show you the &lt;a title="free WPF and Silverlight from the stone" href="http://www.codeplex.com/caliburn"&gt;Caliburn&lt;/a&gt; way of handling this. I’m going to steal John’s viewmodel from the aforementioned post (and hope he doesn’t sue).&lt;/p&gt;  &lt;p&gt;The viewmodel presents a collection of all products and a filtered collection of products. You can modify the filter by calling LoadProducts().&lt;/p&gt;  &lt;pre class="c#:nogutter:nocontrols" name="code"&gt;public class ProductViewModel
{
    public ProductViewModel()
    {
        Products = new ObservableCollection&amp;lt;Product&amp;gt;();

        AllProducts = new ObservableCollection&amp;lt;Product&amp;gt;
                          {
                              new Product {ProductId = 1, ProductName = &amp;quot;Apple&amp;quot;},
                              new Product {ProductId = 2, ProductName = &amp;quot;Orange&amp;quot;},
                              new Product {ProductId = 3, ProductName = &amp;quot;Banana&amp;quot;},
                              new Product {ProductId = 4, ProductName = &amp;quot;Pear&amp;quot;},
                              new Product {ProductId = 5, ProductName = &amp;quot;Grape&amp;quot;},
                              new Product {ProductId = 6, ProductName = &amp;quot;Grapefruit&amp;quot;},
                              new Product {ProductId = 7, ProductName = &amp;quot;Strawberry&amp;quot;},
                              new Product {ProductId = 8, ProductName = &amp;quot;Melon&amp;quot;},
                              new Product {ProductId = 9, ProductName = &amp;quot;Guava&amp;quot;},
                              new Product {ProductId = 10, ProductName = &amp;quot;Kiwi&amp;quot;},
                              new Product {ProductId = 11, ProductName = &amp;quot;Pineapple&amp;quot;},
                              new Product {ProductId = 12, ProductName = &amp;quot;Mango&amp;quot;}
                          };
    }

    public ObservableCollection&amp;lt;Product&amp;gt; AllProducts { get; set; }

    public ObservableCollection&amp;lt;Product&amp;gt; Products { get; set; }

    public void LoadProducts(string filter)
    {
        Products.Clear();
        var query = from p in AllProducts
                    where p.ProductName.ToLower().StartsWith(filter.ToLower())
                    select p;
        foreach (var item in query)
        {
            Products.Add(item);
        }
    }

    public bool CanLoadProducts
    {
        get { return true; }
    }
}&lt;/pre&gt;

&lt;p&gt;Let me point out a few notable differences between John’s original and my version of the viewmodel.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There is no ICommand property. &lt;/li&gt;

  &lt;li&gt;CanLoadProducts is a property on my model, it was a method on the original &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The snippet from the corresponding view would look like this:&lt;/p&gt;

&lt;pre class="xml:nogutter:nocontrols" name="code"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;TextBox x:Name=&amp;quot;filter&amp;quot; /&amp;gt;
    &amp;lt;Button x:Name=&amp;quot;LoadProducts&amp;quot; Content=&amp;quot;Load&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;h3&gt;The Explanation&lt;/h3&gt;

&lt;p&gt;It’s &lt;em&gt;binding by convention&lt;/em&gt;, and it is a new feature of Caliburn added after the 1.1 release&lt;sup&gt;&lt;a id="fn1" title="see footnote"&gt;[1]&lt;/a&gt;&lt;/sup&gt;. So you’ll need to get the &lt;a href="http://caliburn.codeplex.com/SourceControl/list/changesets"&gt;trunk&lt;/a&gt; to do this. &lt;/p&gt;

&lt;p&gt;When you have a button named LoadProducts, Caliburn will look for a method on your viewmodel named LoadProducts and automagically handle the binding for you. In addition, it will check for either a method or property (as in this example) named CanLoadProducts that it will use to toggle the enable/disabled for the button. Also, since we have a parameter named “filter” on LoadProducts, Caliburn will check to see if there is an element in the view name “filter” and pull the value from that.&lt;/p&gt;

&lt;p&gt;There’s a great deal more that you can do with conventions (and you can even plug in your own conventions). &lt;/p&gt;

&lt;p&gt;This also works for Silverlight 3 and WPF. &lt;/p&gt;

&lt;p&gt;You can also see an example of this in &lt;a title="can I get a book?" href="http://github.com/ayende/Alexandria"&gt;Ayende’s sample app Alexandria&lt;/a&gt;.&lt;/p&gt;

&lt;div id="footnote"&gt;
  &lt;ol&gt;
    &lt;li id="1"&gt;&lt;em&gt;&lt;font size="2"&gt;Actually, you can do some of this in 1.0, but it is easier and much richer in the trunk. Ping &lt;/font&gt;&lt;a href="http://caliburn.codeplex.com/Thread/List.aspx"&gt;&lt;font size="2"&gt;the forums&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; if you have a need to use it in 1.x.&lt;/font&gt; &lt;/em&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55619" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/V19lz9-PRfM" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/mvvm/default.aspx">mvvm</category><feedburner:origLink>http://devlicio.us/blogs/christopher_bennage/archive/2010/03/03/1-simple-step-for-commanding-in-silverlight.aspx</feedburner:origLink></item><item><title>Around the World in 90 Days</title><link>http://feedproxy.google.com/~r/Devlicious/~3/jzq1TpDIp6E/around-the-world-in-90-days.aspx</link><pubDate>Tue, 02 Mar 2010 06:38:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55591</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>4</slash:comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Around 3 months ago, I packed up in the UK, and headed to the other side of the world, to Australia.&lt;/p&gt;
&lt;p&gt;Last Autumn I was chatting to &lt;a href="http://www.twitter.com/rbanks54"&gt;Richard Banks&lt;/a&gt; over Twitter, and he mentioned that &lt;a href="http://readify.net/about-readify"&gt;Readify &lt;/a&gt;were looking to hire good .Net developers in Australia. I joked that if they wanted to pay my air fare over I would certainly do an interview.&lt;/p&gt;
&lt;p&gt;Sadly Readify don&amp;#39;t pay for the air fare, but after a bit more joking I took Richard seriously and dropped them a copy of my CV. A few months later, after a fairly thorough interview (part of which took place over Skype and Live Meeting... sadly the reason for no free holiday), I took the decision to join Readify as a Senior Consultant.&lt;/p&gt;
&lt;p&gt;For the last 18 years I have been a self employed consultant / contractor in the UK, and have made a fairly good living at it. In fact this will be the first time I have been an employee since I was aged 22. So this was a fairly big decision.&lt;/p&gt;
&lt;p&gt;What swung it for me was the general positive attitude of the Readify people I spoke to, and their focus on technical excellence and good development practices. This is a company that is rapidly growing, and despite the general world economic conditions, Australia managed to avoid the vast majority of the financial crisis.&lt;/p&gt;
&lt;p&gt;As part of their expansion, Readify are still recruiting, and due to the shortage of good developers in Australia, they are willing to hire from overseas, and deal with all of the immigration and visa issues needed to get you into the country. So far at least one person I have chatted to over Twitter has applied, and if you look &lt;a href="http://twitter.com/rbanks54/readify"&gt;through the list of Readify employees&lt;/a&gt; you are likely to see a number of people who are highly respected in the .Net world - it&amp;#39;s a great bunch of people.&lt;/p&gt;
&lt;p&gt;Apparently only 1% of applicants to &lt;a href="http://readify.net/about-readify/%20"&gt;Readify &lt;/a&gt;get through the interview process, so if you are looking for a new career, are open to moving, and are pretty darn hot around .Net and good development practices, maybe you should think of applying.&amp;nbsp;&lt;a href="http://readify.net/about-readify/careers/"&gt;http://readify.net/about-readify/careers/&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;span&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55591" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/jzq1TpDIp6E" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Readify/default.aspx">Readify</category><category domain="http://devlicio.us/blogs/casey/archive/tags/careers/default.aspx">careers</category><feedburner:origLink>http://devlicio.us/blogs/casey/archive/2010/03/02/around-the-world-in-90-days.aspx</feedburner:origLink></item><item><title>Message-Based Systems for Maintainable, Asynchronous Development</title><link>http://feedproxy.google.com/~r/Devlicious/~3/e-WyxpHMHCk/message-based-systems-for-maintainable-asynchronous-development.aspx</link><pubDate>Tue, 02 Mar 2010 04:22:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55589</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;&lt;strong&gt;Preface&lt;/strong&gt; (you know it&amp;rsquo;s good if there&amp;#39;s a preface)&lt;/p&gt;
&lt;p&gt;In &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/02/03/software-architectural-approaches-for-robotics.aspx"&gt;Architectural Paradigms of Robotic Control&lt;/a&gt;, a number of architectures were reviewed including deliberative, reactive, and hybrid architectures. &amp;nbsp;Each of these exhibit a clean separation of concerns with layering and encapsulation of defined behaviors. &amp;nbsp;When implemented, the various capabilities, such as planners and mobility controllers, are encapsulated into discrete components for better reusability and maintainability. &amp;nbsp;A pivotal aspect &lt;i&gt;not&lt;/i&gt; discussed in the previous article is how the various system layers and components communicate with each other, such as reporting sensor feedback and sending commands to actuator controllers. &amp;nbsp;Effectively resolving this communication challenge is not only important to robotic systems but to many other industries and domains for the successful integration of disparate applications.&lt;/p&gt;
&lt;p&gt;To give credit where credit is due, this article pulls quite heavily&amp;nbsp;from the patterns, taxonomy, and best practices presented in&amp;nbsp;&lt;a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683"&gt;Enterprise Integration Patterns&lt;/a&gt;&amp;nbsp;(Hohpe, 2003). &amp;nbsp;This well organized book is chock full of hard learned lessons and solid guidelines for developing maintainable message-based systems. &amp;nbsp;This article should not be seen as an adequate replacement for that book (it&amp;rsquo;s more like cliff notes with a spackling of robotics bias); indeed,&amp;nbsp;&lt;a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683"&gt;Enterprise Integration Patterns&lt;/a&gt;&amp;nbsp;should have a prominent place on your bookshelf if you&amp;#39;re developing message-based systems&amp;nbsp;&amp;ndash;&amp;nbsp;so read this post and then browse&amp;nbsp;&lt;a href="http://www.eaipatterns.com/"&gt;http://www.eaipatterns.com/&lt;/a&gt;&amp;nbsp;while waiting for your copy to arrive to delve deeper.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A Need for Message-Based Systems&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A few industries in particular, such as finance, healthcare and robotics, are demanding integration of an intimidating number of separate technologies that may be spread across computers, networks, and/or built upon a variety of technological platforms. &amp;nbsp;Not only is this integration tricky, it can come with a significant cost to performance and maintainability if not implemented correctly. &amp;nbsp;Accordingly, a solution is needed which facilitates loosely coupled integration while accommodating the performance demands of the task at hand. &amp;nbsp;Taking a message-oriented approach to inter-application communications is one such way to accommodate these demands in a maintainable manner without sacrificing performance. &amp;nbsp;This article gives an introduction to developing message-based systems using messaging middleware, describes taxonomy for discussing messaging topics and patterns, and includes a number of best practices.&lt;/p&gt;
&lt;p&gt;Before delving further, it&amp;#39;s important to clarify a few terms that will be used frequently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Messaging Middleware&lt;/i&gt; (aka, a message bus): &amp;nbsp;a 3rd party application which provides messaging infrastructure and capabilities (e.g., &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/msmq/default.mspx"&gt;MSMQ&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/bb648752.aspx"&gt;MS Concurrency and Coordination Runtime&lt;/a&gt; (CCR), &lt;a href="http://www.ros.org/wiki/"&gt;Robot Operating System&lt;/a&gt; (ROS)),&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Component&lt;/i&gt;: &amp;nbsp;a stand-alone application or piece of executable code which communicates with the messaging middleware,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Message-based system&lt;/i&gt;: &amp;nbsp;the entirety of the system including all integrated components and the messaging middleware.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As stated, messaging provides one means of facilitating inter-component communications. &amp;nbsp;But as with any design approach, the project requirements must be carefully considered to determine if messaging is the appropriate mechanism for integration. &amp;nbsp;While messaging is robust and facilitates integration, it also adds complexity and indirection. &amp;nbsp;So before deciding to use messaging as the means of integration, consider all component integration options including (Hohpe, 2003):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;File Transfer&lt;/i&gt;: &amp;nbsp;wherein a component produces files of shared data which other components consume,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Shared Database&lt;/i&gt;: &amp;nbsp;each component stores and retrieves data from a common database,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Remote Procedure Invocation&lt;/i&gt;: &amp;nbsp;each component exposes specific procedures to be invoked remotely for exposing behavior and exchanging data,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Messaging&lt;/i&gt;: &amp;nbsp;each component connects to a common messaging system, using messages to invoke behavior and exchange data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Determining which integration approach is most suitable to your project&amp;#39;s needs is beyond the scope of this article, focusing instead specifically on messaging. &amp;nbsp;In turn, we&amp;#39;ll review important elements of developing a message-based system including: &amp;nbsp;message channels, messages, message routers, and message endpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Channels&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When a component sends information to another component in a message-based system, it adds the information to a &lt;i&gt;message channel&lt;/i&gt;. &amp;nbsp;The receiving component then retrieves the information from the message channel. &amp;nbsp;Different channels are created for each kind of data to be carried; having a separate channel for each datatype better enables receiving components to know what kind of data will be retrieved from a given channel. &amp;nbsp;For using a channel, each channel is addressable for sending and retrieving messages to/from them. &amp;nbsp;How a channel is addressed varies depending on the messaging middleware being leveraged, but it&amp;#39;s usually a port number or a unique string identifier. &amp;nbsp;As a good practice for keeping channels organized, if string identifiers are available, a hierarchical naming convention may be employed to label channels by type and name; e.g., a channel carrying laser scans might be called &amp;quot;Perception/LaserScans.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin-top:6px;margin-bottom:6px;margin-left:2px;margin-right:2px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/ChannelTypes.png" border="0" alt="" /&gt;There are two basic kinds of message channels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Point-to-Point Channels&lt;/i&gt; (aka - client/server style): &amp;nbsp;routes messages for components to talk directly with other components; e.g., a remote procedure call to another component. &amp;nbsp;A message over a point-to-point channel only has a single receiver; so while the sender may not necessarily know who the receiver is, the sender can rest assured that the message will only be received by one receiver &amp;ndash; it&amp;rsquo;s a &lt;a href="http://en.wikipedia.org/wiki/FIFO"&gt;FIFO&lt;/a&gt; queue.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Publish-Subscribe Channels&lt;/i&gt; (aka - broadcast): &amp;nbsp;routes messages for components to publish data and an arbitrary number of components to subscribe to that data. &amp;nbsp;A copy of the message is generated for each subscriber on the channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to channels intended to carry information among components, it is a good practice to setup an &lt;i&gt;invalid message channel&lt;/i&gt;&amp;nbsp;that bad-formed or unreadable messages may be forwarded to for logging and to assist with debugging.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Messages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With a function call, a simple parameter or object reference may be passed and retrieved by the invoked method, sharing the same memory space. &amp;nbsp;But when passing data between two processes with separate memory spaces, the data must be packaged into a &amp;quot;message&amp;quot; adhering to an agreed upon format which the receiver will be able to disassemble and understand. &amp;nbsp;The sender of the message passes the message via a message channel. &amp;nbsp;The receiver retrieves the message from the message channel and transforms the message into internal data structures appropriate for the task at hand.&lt;/p&gt;
&lt;p&gt;A message is made up of two parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Header&lt;/i&gt;: &amp;nbsp;describes the data being transmitted and details concerning the message itself; e.g., origin, timestamp information, message expiration (if content is time-sensitive), message identifier, correlation identifier, return address, etc., and&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Body&lt;/i&gt;: &amp;nbsp;the data content that the receiver is looking to use.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When sending a message, the sender intends for the message to be used, or responded to, in a particular way. &amp;nbsp;The intention of the message may be described as being one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Command Message&lt;/i&gt;: &amp;nbsp;invokes a procedure in another application,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Document Message&lt;/i&gt;: &amp;nbsp;passes a set of data to another application,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event Message&lt;/i&gt;: &amp;nbsp;notifies another application of a change in state, and&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Request-Reply&lt;/i&gt;: &amp;nbsp;requests a reply from another application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Event messages deserve a bit more discussion. &amp;nbsp;In its simplest form, an event message would simply be informational, letting subscribers know that an event has occurred; e.g., a new laser scan is available. &amp;nbsp;If subscribers would like details concerning the event, they would send a request-reply to the sender of the event to provide further details; e.g., the laser scan details. &amp;nbsp;Alternatively, the event could be a document &lt;i&gt;as&lt;/i&gt;&amp;nbsp;an event to inform subscribers that an event has occurred along with the details of that event; e.g., a new laser scan is available with laser scan details included. &amp;nbsp;The size of the event details and the rapidity in which the event occurs should be considered when deciding between publishing simple event messages and document messages &lt;i&gt;as&lt;/i&gt; events.&lt;/p&gt;
&lt;p&gt;Request-reply messages could also use a bit more describing. &amp;nbsp;A request-reply is usually implemented as two point-to-point channels. &amp;nbsp;The first channel delivers the request as a command message, while the second carries the reply back to the requestor as a document message. &amp;nbsp;To keep the replying component more loosely coupled and reusable, the requestor should include a &lt;i&gt;return address&lt;/i&gt;&amp;nbsp;indicating the channel that the replier should use to publish the reply. &amp;nbsp;After receiving the reply, a challenge for the requestor is to then correlate the reply to the original request. &amp;nbsp;If the requestor is sending a number of requests in succession, it will likely be difficult to keep clear &amp;ndash; if it matters &amp;ndash; which request a reply is associated with. &amp;nbsp;To resolve this, every request may include a unique &lt;i&gt;message identifier&lt;/i&gt;&amp;nbsp;that the replier would then include as a &lt;i&gt;correlation identifier&lt;/i&gt;. &amp;nbsp;(A message could have both a message Id and a correlation Id.) &amp;nbsp;The requestor uses the correlation identifier to &amp;ldquo;jog its memory&amp;rdquo; concerning which request the response is for. &amp;nbsp;But frequently, a request-reply is in context of a particular domain object, such as a terrain map or a bank transaction; but the correlation Id doesn&amp;rsquo;t include such information. &amp;nbsp;To assist, the requestor can maintain a mapping (e.g., hashtable) between message Ids and relevant domain object Ids which are related to the original request. &amp;nbsp;When the reply is received, the mapping may be used to load the appropriate domain objects and take further action, accordingly.&lt;/p&gt;
&lt;p&gt;Obviously, it is important that the senders and receivers of a message system agree upon the format that messages will take for clear interoperability, better reusability of components, and extensibility of the system. &amp;nbsp;Consequently, a &lt;i&gt;canonical data model&lt;/i&gt;&amp;nbsp;should be well defined that all applications will adhere to. &amp;nbsp;The canonical data model does not dictate how each application&amp;#39;s domain model must be structured, only how each application must format data within messages. &amp;nbsp;&lt;i&gt;Message translators&lt;/i&gt;&amp;nbsp;are developed to convert the sending application&amp;#39;s domain model into the canonical data model before sending a message; receivers of messages then use their own message translators to translate the message into their own domain. &amp;nbsp;This mechanism allows applications built on completely different technologies (e.g., C#, Lisp, and C++) to communicate with each other and exchange data. &amp;nbsp;Many off the shelf messaging systems define their canonical data model which must be adhered to. &amp;nbsp;For example, the &lt;a href="http://www.ros.org/wiki/"&gt;Robot Operating System&lt;/a&gt; (ROS), which we&amp;#39;ll looking at in more detail in subsequent posts, defines their canonical model at &lt;a href="http://www.ros.org/wiki/msg"&gt;http://www.ros.org/wiki/msg&lt;/a&gt;. &amp;nbsp;But the canonical data model need not be limited to defining the types of primitives available and how to include them in messages.&lt;/p&gt;
&lt;p&gt;Domain-specific canonical data models may augment message formatting rules, adding semantic meaning to the data within a message. &amp;nbsp;For example, the &lt;a href="http://en.wikipedia.org/wiki/JAUS"&gt;Joint Architecture For Unmanned Systems (JAUS)&lt;/a&gt; is a set of message guidelines for the domain of unmanned systems, such as autonomous vehicles. &amp;nbsp;The JAUS guidelines provide domain specific rules for communicating data, such as propulsion and braking commands, sensor events, pose and location information, etc. &amp;nbsp;To demonstrate, JAUS message types include (Siciliano, 2008):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Command&lt;/i&gt;: &amp;nbsp;initiate mode changes or actions,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Query&lt;/i&gt;: &amp;nbsp;used to solicit information from a component,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Inform&lt;/i&gt;: &amp;nbsp;response to a query,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event set up&lt;/i&gt;: &amp;nbsp;passes parameters to set up an event, and&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event notification&lt;/i&gt;: &amp;nbsp;sent when the event happens.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A challenge in dealing with canonical data models is how to handle changes to the model. &amp;nbsp;In order to support backwards compatibility of existing components when the canonical data model changes, new message channels could be created to carry the messages adhering to the model; e.g., &amp;quot;Perception/LaserScans_V1&amp;quot; and &amp;quot;Perception/LaserScans_V2.&amp;quot; &amp;nbsp;Alternatively, the existing channels could continue to be leveraged to carry messages adhering to different version of the canonical data model. &amp;nbsp;To do so, the message, within its header, would include a &lt;i&gt;format indicator&lt;/i&gt;, such as a version number or format document (e.g., DTD) reference. &amp;nbsp;But if a sender knows that receivers of a particular message are mixed in what format is being used, a component would need to send two messages, one for each version of the canonical data model. &amp;nbsp;Certainly, this is an important consideration when deciding which components should (or even can) be upgraded to newer formats, and in what order.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Routers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While the heavy lifting of the message routing is handled by the messaging middleware itself, there are times when it is useful to augment the middleware with custom message routers to support unique scenarios.&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin-left:2px;margin-right:2px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/MessageRouter.png" border="0" alt="" /&gt;Suppose the destination of a message may change based on the number of messages that have already passed over a channel. &amp;nbsp;In this scenario, the sender of a message may not know how many messages have been passed over a channel since other senders may have been publishing messages on the same channel. &amp;nbsp;Consequently, a message router may subscribe to the channel to determine where each message should be forwarded to, based on the described business rules. &amp;nbsp;Once the destination is determined, the router would then place the message on a subsequent channel to be delivered to the appropriate destination. &amp;nbsp;This intermediary routing is described as &lt;i&gt;predictive routing&lt;/i&gt;&amp;nbsp;as the message router is aware of every possible destination and the rules for routing, accordingly. &amp;nbsp;If the routing is based on content within the message itself, such as threshold values, then the custom router is known as a &lt;i&gt;content-based router&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;A drawback to using message routers is that if the routing rules change frequently, the message router will need to be modified just as often. &amp;nbsp;To help remedy this, if the rules are expected to change frequently, configurable routing rules (e.g., via XML) could be employed to enable easier management of routing rules.&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin-left:2px;margin-right:2px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/MessageFilter.png" border="0" alt="" /&gt;Let&amp;#39;s now consider another scenario wherein it&amp;#39;s left up to the subscribers to determine which messages they&amp;#39;re interested in; i.e., subscribers will be responsible for filtering out the messages they&amp;#39;re uninterested in. &amp;nbsp;In this &lt;i&gt;reactive routing&lt;/i&gt; scenario, each subscriber would provide a respective &lt;i&gt;message filter&lt;/i&gt;&amp;nbsp;which is similar to a message router, but simply forwards, or does not forward, a message onto a subsequent channel that the destination subscriber is listening to. &amp;nbsp;Frequently, message filters decide to forward, or not forward, based on content in the message itself; e.g., only forwarding orders that have a coupon included. &amp;nbsp;While being similar to a message router in basic functionality, a message filter only has one possible channel to forward the message onto.&lt;/p&gt;
&lt;p&gt;Deciding between predictive and reactive filtering must take into account a number of considerations. &amp;nbsp;Is the message content sensitive? &amp;nbsp;Do you need to minimize network traffic? &amp;nbsp;Do you need to be able to add and remove subscribers easily? &amp;nbsp;Is the predictive router becoming a bottleneck of message dissemination? &amp;nbsp;For further guidance on selecting among routing options, see (Hohpe, 2003), ppg. 241-242.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Endpoints&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Each messaging middleware option (e.g., CCR, ROS) has unique requirements for communicating with it. &amp;nbsp;Each has its own API, its own means of addressing channels, and its own rules for packaging messages. &amp;nbsp;Ideally, the components of the system should not be aware of the specifics of communicating with the messaging middleware. &amp;nbsp;Furthermore, while unlikely to occur, the middleware should be able to be replaced with another, requiring little, if any, changes to the components. &amp;nbsp;Accordingly, the components must be loosely coupled to the messaging middleware. &amp;nbsp;&lt;i&gt;Message endpoints&lt;/i&gt;&amp;nbsp;provide the bridge between the domain of each component and the API of the messaging middleware.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/MessageEndpoints.png" style="border:0;float:right;margin-left:2px;margin-right:2px;" alt="" /&gt;Message endpoints are similar in nature to &lt;a href="http://domaindrivendesign.org/node/123"&gt;repositories&lt;/a&gt; when communicating with a database. &amp;nbsp;Repositories encapsulate the code required to communicate with a database to store and retrieve data while being able to convert information from the database into domain objects. &amp;nbsp;If the database changes, or if the mechanism for database communication changes (e.g., ADO.NET to NHibernate), then, ideally, only the repositories are affected. &amp;nbsp;The rest of the application knows little about database communications outside of the repository interfaces. &amp;nbsp;Likewise, components of a message-based system should not be aware of messaging details outside of the message endpoint interfaces, which provide the means to send and receive data. &amp;nbsp;The message endpoint accepts a command or data, converts it into a message, and publishes it onto the correct channel. &amp;nbsp;Additionally, the message endpoint receives messages from a channel, converts the content into the domain of the component, and passes the domain objects to the component for further action. &amp;nbsp;Internally, the message endpoint implements a &lt;i&gt;message mapper&lt;/i&gt; to convert between the component domain objects and the canonical data model.&lt;/p&gt;
&lt;p&gt;While posting to a channel is rather straight forward, a message endpoint may receive a message by acting as a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Polling Consumer&lt;/i&gt;: &amp;nbsp;wherein the receiver looks at a channel on a regular basis for new messages and/or as soon as it completes the processing of a previous message. &amp;nbsp;This frees the receiver from having to deal with messages as soon as they arrive on the channel in favor of dealing with messages went it&amp;rsquo;s ready and willing. &amp;nbsp;A consideration to keep in mind is that messages may queue up on a channel while waiting to be retrieved by the polling consumer. &amp;nbsp;Additionally, a polling consumer may take up threads and resources while polling a channel, even if the channel is empty.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event-Driven Consumer&lt;/i&gt;: &amp;nbsp;wherein the message is given to the receiver as soon as it arrives on the channel. &amp;nbsp;The benefits to this include avoiding messages queuing up while being able to process messages asynchronously. &amp;nbsp;But the receiver is no longer in control of the timing in which it processes messages and must handle messages as soon as they arrive on a channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many messaging middleware solutions include support for transactions that the message endpoints may leverage, making the endpoints &lt;i&gt;transactional clients&lt;/i&gt;. &amp;nbsp;To illustrate the need for this, suppose the receiver of a request-reply command crashes just moments after the command message is consumed and removed from the channel. &amp;nbsp;When it recovers, the command message is lost and the sender will never receive a reply. &amp;nbsp;Using a transaction, the command message is not removed from the channel until the response is completed and sent. &amp;nbsp;Committing the transaction removes the command message from the channel and adds the reply document message to the reply channel.&lt;/p&gt;
&lt;p&gt;There are a few recommendations which should be considered when developing message endpoints. &amp;nbsp;In accordance with the &lt;a href="http://www.objectmentor.com/resources/articles/srp.pdf"&gt;SRP&lt;/a&gt;, message endpoints should be able to receive messages or send messages, but not both in the same message endpoint. &amp;nbsp;Furthermore, a message endpoint should only communicate with one message channel. &amp;nbsp;If a component needs to send a message on separate channels, it would leverage multiple message endpoints to do so. &amp;nbsp;If your components are developed in line with &lt;a href="http://www.infoq.com/minibooks/domain-driven-design-quickly"&gt;DDD&lt;/a&gt;, it would be each component&amp;#39;s &lt;a href="http://martinfowler.com/eaaCatalog/serviceLayer.html"&gt;application services layer&lt;/a&gt; which would communicate with the message endpoints, preferably via their interfaces instead of concrete instances. &amp;nbsp;This facilitates swapping out the message endpoints with mock objects for unit testing. &amp;nbsp;Leveraging &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2008/10/30/refactoring-service-dependencies-to-separated-interface.aspx"&gt;separated interfaces&lt;/a&gt;&amp;nbsp;and &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2009/11/09/dependency-injection-101.aspx"&gt;dependency injection&lt;/a&gt;&amp;nbsp;helps enable this approach. &amp;nbsp;While these guidelines introduce more objects and indirection, they are proven practices for increasing maintainability of the component and reusability of the message endpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Performance of Message Based Systems&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One would likely be quick to assume that developing a message-based system has a huge cost to performance. &amp;nbsp;Domain objects are converted to messages, messages are passed over channels, routers and filters intercept and forward messages, and messages are converted back into domain objects...this sounds like a heck of a lot going on. &amp;nbsp;But because each component executes in its own thread or process, they need not wait for other components to complete their job before being able to move on to handling another message or task.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/SynchVsAsynchProcessing.png" border="0" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;In the figure above (adapted from&amp;nbsp;Hohpe, 2003, pg. 73), note that a sequential process requires that each message life cycle is completed in full before moving on to the next message. &amp;nbsp;But in an asynchronous, message-based system, each component can move onto a subsequent message just as soon as it has completed its part in the last one. &amp;nbsp;This greatly compensates for the extra overhead imparted by the messaging infrastructure.&lt;/p&gt;
&lt;p&gt;With that said, there are some component responsibilities which take a long time to complete and may impede the speed by which messages are processed. &amp;nbsp;For example, imagine a component which takes images from a web cam and extracts information such as human figures or road signs. &amp;nbsp;This is likely a time consuming process and would impact the turn around time in which the component could process subsequent messages. &amp;nbsp;To alleviate this bottleneck, multiple instances of the same component may subscribe to the same point-to-point channel. &amp;nbsp;Recall that a point-to-point channel ensures that each message only has a single receiver. &amp;nbsp;The instances of the component then become &lt;i&gt;competing consumers&lt;/i&gt; of each message. &amp;nbsp;So if one instance of the component is still processing an earlier message, another instance can grab the next message that arrives for concurrent processing. &amp;nbsp;Power in numbers!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monitoring and Debugging&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Due to the widely asynchronous nature of message-based systems, attention must be given to monitoring and debugging techniques to observe system behavior and iron out problems.&lt;/p&gt;
&lt;p&gt;Logging message content is an invaluable measure towards getting a clear look at what communications are taking place. &amp;nbsp;To facilitate this, logging could be added directly into sending and receiving components, but logging message content should not be a concern of components; accordingly, using a monitoring utility to log such information is a cleaner separation of concerns. &amp;nbsp;Certainly a benefit of publish-subscribe channels is that a monitoring component may subscribe to all messages and log the information to a file or console window. &amp;nbsp;While it&amp;rsquo;s just as valuable to monitor messages on point-to-point channels, if a monitor were to consume a message over a point-to-point channel, the message would be noted as consumed and would no longer be available to the intended receiver. &amp;nbsp;Because such monitoring capability is so helpful in developing and debugging, many messaging middleware options include a &amp;quot;peek&amp;quot; option which allows a monitoring utility to review message contents on a point-to-point channel without actually consuming the message. &amp;nbsp;This capability should be taken into consideration when comparing messaging middleware alternatives.&lt;/p&gt;
&lt;p&gt;In addition to monitoring message content sent over channels, it&amp;rsquo;s also assistive to monitor active subscriptions to various channels to accurately determine which components are receiving which messages. &amp;nbsp;This capability is typically built into messaging middleware solutions and is very assistive during development.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s possible that even if a message is routed appropriately, the receiving component may not know what to do with the message due to an incorrectly formatted header or body content. &amp;nbsp;Invalid messages such as this should be forwarded to an &lt;i&gt;invalid message channel&lt;/i&gt; which an error logging utility would monitor and log, accordingly. &amp;nbsp;An invalid message channel is setup just like any other channel but with the intention of exposing such messages for debugging purposes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Closing Thoughts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Developing asynchronous, message-based systems requires a paradigm shift from the more traditional, synchronously executed applications that most people are familiar with. &amp;nbsp;It is not appropriate for every application domain and should be seen as one additional architectural option to consider when developing applications. &amp;nbsp;But in some domains, such as robotics or in the integration of disparate applications, this approach to development is absolutely pivotal in providing responsive behavior without sacrificing maintainability of the overall system. &amp;nbsp;Indeed, by splitting responsibilities into discrete components, loosely coupled to each other via messaging middleware, immensely complex problems can be broken down into understandable chunks while being flexible enough to accommodate changes to the underlying middleware or introduction of new components.&lt;/p&gt;
&lt;p&gt;In the next couple of posts, we&amp;#39;ll look at a checklist for developing message-based systems followed with examples in CCR and ROS.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;br /&gt;&lt;a href="http://wiki.sharparchitecture.net"&gt;http://wiki.sharparchitecture.net&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;P.S., for S#arp fans, we&amp;#39;re trying to get another release together for the coming week...and this ain&amp;#39;t no quarterly release. ;)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hohpe, G., Woolf, B. &amp;nbsp;2003. &amp;nbsp;&lt;a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683"&gt;Enterprise Integration Patterns: &amp;nbsp;Designing, Building, and Deploying Messaging Solutions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Siciliano, B., Khatib, O. &amp;nbsp;2008. &amp;nbsp;&lt;a href="http://www.amazon.com/Springer-Handbook-Robotics-Bruno-Siciliano/dp/354023957X"&gt;Springer Handbook of Robotics&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55589" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/e-WyxpHMHCk" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Robotics/default.aspx">Robotics</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Patterns/default.aspx">Patterns</category><feedburner:origLink>http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/01/message-based-systems-for-maintainable-asynchronous-development.aspx</feedburner:origLink></item><item><title>MSpec Live Templates</title><link>http://feedproxy.google.com/~r/Devlicious/~3/EqIBAg0cAJc/mspec-live-templates.aspx</link><pubDate>Mon, 01 Mar 2010 15:07:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55580</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re using MSpec (&lt;a href="http://github.com/machine/machine.specifications"&gt;Machine.Specifications&lt;/a&gt;), you&amp;rsquo;ve no doubt run into the verbosity of it. Here&amp;rsquo;s a typical specification in MSpec&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3ce97efd-5c56-4b7e-b368-f1899582fb49" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#000000;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;[&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;Subject&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Registering as new a usergroup&amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;)]&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;class&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;when_requesting_registration_page&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#6897bb;"&gt;Establish&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; context = () =&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;};&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#6897bb;"&gt;Because&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; of = () =&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;};&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#6897bb;"&gt;It&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; should_display_blank_registration_form = () =&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;};&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;}&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The code is usually divided into three areas, the &lt;i&gt;Establish &lt;/i&gt;that defines the context, &lt;i&gt;Because &lt;/i&gt;which is defined as the action to take, and finally one or more benefits that are defined as &lt;i&gt;It&lt;/i&gt; sections. Having this layout makes it easier to understand specifications and both the console runner as well as ReSharper&amp;rsquo;s MSpec runner remove underscores and provide a nice formatting. &lt;/p&gt;
&lt;h3&gt;Live Templates&lt;/h3&gt;
&lt;p&gt;However when it comes to typing all this in, well all those brackets and symbols become tiring. For that I normally use &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; Live Templates. If you&amp;rsquo;re not familiar with these, think of them as code snippets that allow interaction. Each template is uniquely identified by a shortcut, which is a series of characters. To invoke it, you simply type the characters and hit TAB. It then inserts some code. Up to this point it&amp;rsquo;s like a normal snippet. The twist however is that you can then TAB through placeholders and define values (I&amp;rsquo;ll cover&amp;nbsp; Live Templates and all the possibilities it allows in a future post). &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_2B76B94F.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_1BF3A780.png" border="0" height="186" width="397" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;What I&amp;rsquo;ve been using for a while are some Live Templates for MSpec that allow me to define specifications with a little less effort. The first one is for empty specifications, which is useful for defining scenarios for features and then later proceeding to implement them, named &lt;i&gt;espec&lt;/i&gt;. The second one is for the specifications and implementation, named &lt;i&gt;spec&lt;/i&gt;. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_7C6457AA.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_5EA2CCEB.png" border="0" height="305" width="394" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;To install them, the easiest way is to just open up Live Templates (ReSharper menu) and Import the &lt;a href="http://hadihariri.com/Downloads/mspecbasiclivetemplate.xml"&gt;following file&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; .   &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_76E5C139.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_272C95F0.png" border="0" height="186" width="335" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Obviously these are just two simple versions and can be expanded on. For instance, if you use Behaviors in MSpec, you could write an additional one for that. Feel free to use them for your own needs. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55580" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/EqIBAg0cAJc" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ReSharper/default.aspx">ReSharper</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/MSpec/default.aspx">MSpec</category><feedburner:origLink>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/01/mspec-live-templates.aspx</feedburner:origLink></item><item><title>Coding Concepts are Cross Language, because it is SQL does not means it should suck</title><link>http://feedproxy.google.com/~r/Devlicious/~3/K3rEXYu1pVA/coding-concepts-are-cross-language-just-because-it-is-sql-means-it-can-suck.aspx</link><pubDate>Mon, 01 Mar 2010 11:49:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55578</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;&amp;lt;Warning_Rant_AHead&amp;gt;&lt;/p&gt;
&lt;p&gt;Today I was reviewing some commits by our team and I ran into one commit in general that first made me vomit a bit in my mouth, then get pissed as all hell that we committed code like this.&lt;/p&gt;
&lt;p&gt;The code that was committed was a minor change to one of our &amp;lsquo;legacy&amp;rsquo; (aka has no tests, written like a blind monkey coded it and god help the person who has to make changes to it) stored procs.&amp;nbsp; Here are some details on the proc&lt;/p&gt;
&lt;p&gt;Has about 2050 lines of code 
  &lt;br /&gt;Has about 141 variables 
  &lt;br /&gt;Has 6 Temp tables 
  &lt;br /&gt;Has &amp;gt; 50 update statements 
  &lt;br /&gt;Has ~13 delete statements 
  &lt;br /&gt;Has 8 Cursors&lt;/p&gt;
&lt;p&gt;What makes me so mad is that this code when it was originally written was code reviewed by a senior developer on the team (I know this be cause like many other old school shops at that time we put our commit comments in the header of every file).&amp;nbsp; I am going to bet the farm that had this been C# code and not SQL this would not have passed review.&amp;nbsp; BUT for what ever reason SQL seems to be treated differently.&amp;nbsp; When writing SQL many people throw best practices out the window, and I have NO clue why.&lt;/p&gt;
&lt;p&gt;The one message I want to get across to anyone out there reading this is&amp;hellip;. Code is Code and coding concepts are cross language.&amp;nbsp; If while writing .net/java/ruby/etc code you follow practices like SRP, DRY, etc then why not follow those same principles when writing code in SQL (or any language for that fact)&lt;/p&gt;
&lt;p&gt;&amp;lt;/Warning_Rant_AHead&amp;gt;&lt;/p&gt;
&lt;p&gt;Till next time&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55578" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/K3rEXYu1pVA" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Best+Practice/default.aspx">Best Practice</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Rant/default.aspx">Rant</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Craftsmanship/default.aspx">Craftsmanship</category><feedburner:origLink>http://devlicio.us/blogs/derik_whittaker/archive/2010/03/01/coding-concepts-are-cross-language-just-because-it-is-sql-means-it-can-suck.aspx</feedburner:origLink></item><item><title>Issues Compiling VS2010 solutions (with web projects) from Nant</title><link>http://feedproxy.google.com/~r/Devlicious/~3/pZ4u99pOOEg/issues-compiling-vs2010-solutions-with-web-projects-from-nant.aspx</link><pubDate>Sat, 27 Feb 2010 14:40:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55572</guid><dc:creator>Derik Whittaker</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Recently I upgraded a project of mine (the &lt;a href="http://www.dimecasts.net/Home"&gt;Dimecasts&lt;/a&gt; code base) to use VisualStudio 2010.&amp;nbsp; In the process everything worked just fine from the IDE, but when I tried to compile it from the command line I would get the following errors:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Error MSB4064: The &amp;quot;Retries&amp;quot; parameter is not supported by the &amp;quot;Copy&amp;quot; task. 
    &lt;br /&gt;Error MSB4063: THe &amp;quot;Copy&amp;quot; task could be initialized with its input parameter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After a bit a googling I came across a post which (and of course i cannot find it now) said that if you open up your .proj files and change the line that pointed to the v10.0 build of web applications and reset it back to 9.0 everything would compile.&amp;nbsp; And this did work... BUT when you try to open that project up again in VS 2010 it will simply revert your changes... this is not a working solution.&lt;/p&gt;
&lt;p&gt;
  &lt;br /&gt;Next I decided to switch my target framework in Nant from 3.5 to 4.0, but of course my nant.exe.config file does not support 4.0 yet.&amp;nbsp; So after a bit more googling I found this &lt;a href="http://paigecsharp.blogspot.com/2009/08/nant-net-framework-40-configuration.html"&gt;post&lt;/a&gt; that gives details on how to add the missing values to the config file.&lt;/p&gt;
&lt;p&gt;When I added the config information to my Nant.exe.config file things were better, but still not great.&amp;nbsp; Now I was getting an error that said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
    &lt;br /&gt;The &amp;quot;vendor&amp;quot; attribute does not exist, or has no value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
  &lt;br /&gt;To resolve this I added the following under the &amp;lt;framework&amp;gt; node in my config 

  &lt;br /&gt;vendor=&amp;quot;Microsoft&amp;quot; 

  &lt;br /&gt;

  &lt;br /&gt;After this I got another error.... This time it said that .Net Framework 4.0 was not installed.&amp;nbsp; But I know this is not valid.&amp;nbsp; After looking at the information for a few more seconds I realized the issue.&amp;nbsp; The example config from the post above was build on an older version of the 4.0 framework (.20506) and I have .30128. 

  &lt;br /&gt;

  &lt;br /&gt;I changed all values in the nant.exe.config value that was v4.0.20506 to be v4.0.30128 and NOW I am able to compile.&lt;/p&gt;
&lt;p&gt;So long story short, if you are getting the MSB4064 error you need to do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Point nant to use the 4.0 framework tools &lt;/li&gt;
&lt;li&gt;Follow this &lt;a href="http://paigecsharp.blogspot.com/2009/08/nant-net-framework-40-configuration.html"&gt;post&lt;/a&gt;&amp;nbsp; and copy the framework section to your Nant.exe.config file &lt;/li&gt;
&lt;li&gt;Add the missing &amp;#39;vendor&amp;#39; attribute to the new framework section &lt;/li&gt;
&lt;li&gt;Update the version in the new framework section to match the version you have on disk (check C:\Windows\Microsoft.NET\Framework for versions) &lt;/li&gt;
&lt;li&gt;Compile again &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;br /&gt;Till next time,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55572" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/Devlicious/~4/pZ4u99pOOEg" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/.Net+IDE/default.aspx">.Net IDE</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/.Net/default.aspx">.Net</category><category domain="http://devlicio.us/blogs/derik_whittaker/archive/tags/Nant/default.aspx">Nant</category><feedburner:origLink>http://devlicio.us/blogs/derik_whittaker/archive/2010/02/27/issues-compiling-vs2010-solutions-with-web-projects-from-nant.aspx</feedburner:origLink></item></channel></rss>
