<?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/" version="2.0"><channel><title>.NET &amp; Funky Fresh</title><link>http://devlicio.us/blogs/rob_eisenberg/default.aspx</link><description>Check out the &lt;a href="http://www.amazon.com/gp/product/0672329859?&amp;amp;camp=212361&amp;amp;linkCode=wey&amp;amp;tag=bluspiconinc-20&amp;amp;creative=380733"&gt;WPF book&lt;/a&gt; &lt;a href="http://devlicio.us/blogs/christopher_bennage/default.aspx"&gt;CB&lt;/a&gt; and I authored!</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/FunkyFresh" type="application/rss+xml" /><item><title>Asynchronous Execution, Animation and more in MVVM with Caliburn</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/07/10/asynchronous-execution-animation-and-more-in-mvvm-with-caliburn.aspx</link><pubDate>Fri, 10 Jul 2009 04:21:24 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:49321</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=49321</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/07/10/asynchronous-execution-animation-and-more-in-mvvm-with-caliburn.aspx#comments</comments><description>&lt;p&gt;On the Silverlight Insiders mailing list there’s been a discussion about the difficulties of handling animations when trying to use an MVVM architecture.&amp;nbsp; I’m not going to go into the details here, as I am going to cover this more fully in a future blog post, but still, I could not resist showing off the elegant way that Caliburn solves this problem.&amp;nbsp; Here is some XAML:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;TextBox x:Name=&amp;quot;username&amp;quot; /&amp;gt;
&amp;lt;PasswordBox x:Name=&amp;quot;password&amp;quot; /&amp;gt;

&amp;lt;Button Content=&amp;quot;Login&amp;quot;
        pf:Message.Attach=&amp;quot;Login(username.Text, password)&amp;quot; /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;And here is the code from the ViewModel that Caliburn execute when the user clicks the button: &lt;pre&gt;&lt;/pre&gt;&lt;pre class="brush: xml;"&gt;public IEnumerable&amp;lt;IResult&amp;gt; Login(string username, string password)
{
    _credential.Username = username;
    _credential.Password = password;

    var result = new Result();
    var request = new GetUserSettings(username);

    yield return new ProcessQuery(request, result, &amp;quot;Logging In...&amp;quot;);

    if (result.HasErrors)
    {
        yield return new ShowMessageBox(&amp;quot;The username or password provided is incorrect.&amp;quot;, &amp;quot;Access Denied&amp;quot;);
        yield break;
    }

    var response = result.GetResponse(request);

    if(response.Permissions == null || response.Permissions.Count &amp;lt; 1)
    {
        yield return new ShowMessageBox(&amp;quot;You do not have permission to access the dashboard.&amp;quot;, &amp;quot;Access Denied&amp;quot;);
        yield break;
    }

    _context.Permissions = response.Permissions;

    yield return new OpenWith&amp;lt;IShell, IDashboard&amp;gt;();
}
&lt;/pre&gt;
&lt;p&gt;Please note that the 1st, 2nd and 3rd yield statements above are all *asynchronous*, but the code within this action is executed in sequential order.&amp;nbsp; The 1st yield also triggers an animation...I can also do things like this:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;yield return new BeginAnimation(&amp;quot;MyCoolAnimation&amp;quot;);
yield return new BeginAnimation(&amp;quot;This animation is next&amp;quot;);
yield return new BeginAnimation(&amp;quot;This animation plays last&amp;quot;);
&lt;/pre&gt;
&lt;p&gt;This gives the View Model a declarative way to handle animations without a need to reference the view.&amp;nbsp; Also, it should be noted that the above action relies on several UI services, but I can unit test this action without needing to mock anything.&amp;nbsp; The declarative nature of the action allows me to iterate over the results and simply use normal Asserts on the values.&amp;nbsp; Async programming becomes synchronous and playing Animations is peachy ;)&lt;/p&gt;
&lt;p&gt;More on this later, but I just had to show some code because I’m not sure many people know you can do this with Caliburn.&amp;nbsp; On my current Silverlight project, we are making extensive use of this.&amp;nbsp; It makes calling web services a breeze.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=49321" width="1" height="1"&gt;</description></item><item><title>MVVM – Philosophy and Case Studies - Introduction</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/07/07/mvvm-philosophy-and-case-studies-introduction.aspx</link><pubDate>Wed, 08 Jul 2009 02:49:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:49128</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>11</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=49128</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/07/07/mvvm-philosophy-and-case-studies-introduction.aspx#comments</comments><description>&lt;p&gt;There&amp;rsquo;s been a lot of talk lately about MVVM (Model-View-ViewModel) in the WPF and Silverlight space.&amp;nbsp; Recently, &lt;a href="http://neverindoubtnet.blogspot.com/2009/05/birth-and-death-of-m-v-vm-triads.html"&gt;Ward Bell had an interesting post on the subject&lt;/a&gt; where he digs into some of the patterns he is using to support his MVVM triads.&amp;nbsp; The WPF/Silverlight community is constantly droning MVVM, but almost no one goes beyond stating their use of the pattern or giving an overly general description of it. That&amp;rsquo;s why I enjoyed &lt;a href="http://neverindoubtnet.blogspot.com/2009/05/birth-and-death-of-m-v-vm-triads.html"&gt;Ward&amp;rsquo;s post&lt;/a&gt;.&amp;nbsp; He&amp;rsquo;s trying to get into the nitty-gritty of his UI architecture rather than just chanting &amp;ldquo;I&amp;#39;m using MVVM&amp;quot; and leaving it at that.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m pleased that the WPF/SL community is taking UI architecture seriously, but I think we have a long way to go.&amp;nbsp; We need to dig deeper into the &amp;ldquo;how&amp;rdquo; of the MVVM and realize that a solid implementation is more that just creating a model and binding it to a view, with a dash of the &lt;a href="http://www.dofactory.com/Patterns/PatternCommand.aspx"&gt;Command&lt;/a&gt; pattern thrown in for good measure.&amp;nbsp; In fact, saying you are using MVVM for WPF/Silverlight is sort of like saying you are using MVC for web development.&amp;nbsp; It more or less states the general design approach you are taking to the UI architecture, but doesn&amp;rsquo;t say much about how the pattern is implemented or how individual features are represented within the &lt;em&gt;context&lt;/em&gt; of that design.&amp;nbsp; If you&amp;rsquo;ve been following the blogs on ASP.NET MVC, you&amp;rsquo;ve probably discovered that there is a lot more to it than just having Models, Views and Controllers.&amp;nbsp; It is easy to use the MVC pattern very poorly and the same goes for MVVM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Speaking of context&amp;hellip;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I first read the GoF book, I was baffled by its insistence that patterns were not tied to implementation.&amp;nbsp;&amp;nbsp; Sure, I understood that the &lt;a href="http://www.dofactory.com/Patterns/PatternIterator.aspx"&gt;Iterator&lt;/a&gt; pattern would be implemented differently in C++ than in C#, but I didn&amp;rsquo;t understand that other context-specific factors had a massive affect on the details of its implementation.&amp;nbsp; This &amp;ldquo;phenomena&amp;rdquo; manifests itself in greater degrees with respect to how high-level the pattern is.&amp;nbsp; A high-level pattern like MVC is a fine example of this.&amp;nbsp; Consider how the implementations would differ between a WinForms and an ASP.NET implementation of this pattern.&amp;nbsp; They would not resemble each other much at all.&amp;nbsp; The WinForms version would likely look a lot like an &lt;a href="http://www.dofactory.com/Patterns/PatternObserver.aspx"&gt;Observer&lt;/a&gt; or &lt;a href="http://www.dofactory.com/Patterns/PatternMediator.aspx"&gt;Mediator&lt;/a&gt; while the ASP.NET version would be very similar to a &lt;a href="http://www.dofactory.com/Patterns/PatternStrategy.aspx"&gt;Strategy&lt;/a&gt;.&amp;nbsp; In fact the WinForms version would look so different, you might not even call it MVC anymore, though you started out with an MVC mindset.&amp;nbsp; You could force the WinForms and ASP.NET implementations to look alike, but you would be creating a leaky abstraction by forcing an &lt;em&gt;artificial context&lt;/em&gt; for your design to live in.&lt;/p&gt;
&lt;p&gt;In the next couple of posts I am hoping to examine MVVM within the context of WPF/SL.&amp;nbsp; What does the base form of it look like?&amp;nbsp; What do more complex forms look like?&amp;nbsp; Why is this pattern a good fit for WPF/SL?&amp;nbsp; How does this pattern relate to MVP and MVC?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MVVM &amp;ndash; A Simplistic View&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If we take MVVM as a high level pattern, like MVC, then it becomes our general approach to architecting user interfaces.&amp;nbsp; It means that we will have components in three of the following &lt;em&gt;broad&lt;/em&gt; roles:&lt;/p&gt;
&lt;p&gt;Models &amp;ndash; These are the business-oriented components that are intended to be displayed or manipulated by the application.&amp;nbsp; They might be traditional business objects rehydrated from the DB, messages from a web service or anything else that has business meaning independent of presentation.&lt;/p&gt;
&lt;p&gt;Views &amp;ndash; WPF/Silverlight is a view framework and is thus intended to provided these components.&amp;nbsp; Their role is to display something on the screen.&amp;nbsp; Nothing more, nothing less.&lt;/p&gt;
&lt;p&gt;View Models &amp;ndash; This is a special type of model, intended to be an abstraction of the UI.&amp;nbsp; You can think of it as a &lt;em&gt;logical representation&lt;/em&gt; of the UI.&amp;nbsp; It is &amp;ldquo;connected&amp;rdquo; to the view at runtime through databinding.&lt;/p&gt;
&lt;p&gt;My guess is that you probably feel pretty comfortable with the idea of a Model or a View.&amp;nbsp; You can picture them in your mind.&amp;nbsp; But when it comes to View Models, things get foggy.&amp;nbsp; It means that we need to have a lot more discussion around what our View Models look like.&amp;nbsp; But, we cannot just discuss them abstractly.&amp;nbsp; We must look at specific scenarios and see how ordinary design patterns interplay to create a meaningful model of the UI.&amp;nbsp; In a few words, here&amp;rsquo;s my general philosophy and what I hope will become clear as we proceed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The same OOD techniques you use to build your backend systems are used to construct your View Models.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To that end, I am hoping to put together several posts on the subject.&amp;nbsp; I am planning to contact several of my previous clients with the intention of gaining permission to discuss small portions of their applications; or to discuss them at a very high level.&amp;nbsp; I want to show specific problems and demonstrate how we used common design patterns to build a rich View Model.&amp;nbsp; It is my hope that this will begin a richer discussion on the topic within our community.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=49128" width="1" height="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/.NET+3.0/default.aspx">.NET 3.0</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/Silverlight/default.aspx">Silverlight</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></item><item><title>Caliburn v1 Release Candidate</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/06/13/caliburn-v1-release-candidate.aspx</link><pubDate>Sat, 13 Jun 2009 04:19:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:47896</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=47896</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/06/13/caliburn-v1-release-candidate.aspx#comments</comments><description>&lt;p&gt;On Friday I published the Release Candidate for Caliburn.&amp;nbsp; You can get it &lt;a target="_blank" href="http://caliburn.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28706"&gt;here&lt;/a&gt;.&amp;nbsp; I&amp;rsquo;m hoping to only do bug fixes and a few minor changes between now and release.&amp;nbsp; There have been quite a few important changes since the Beta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Refactored assemblies for greater ease of use. &lt;/li&gt;
&lt;li&gt;Implemented an Application base class that supports model-first development. &lt;/li&gt;
&lt;li&gt;Introduced IViewStrategy and the View.Model attached property. &lt;/li&gt;
&lt;li&gt;Added CommandSource triggers &lt;/li&gt;
&lt;li&gt;Tweaked the implementation of Actions/Commands so that it performs better and is more intelligent &lt;/li&gt;
&lt;li&gt;Updated dependencies on other OSS projects&lt;/li&gt;
&lt;li&gt;Added a WPF version of the LOB Sample &lt;/li&gt;
&lt;li&gt;Factored out mini-frameworks for the both the WPF and Silverlight LOB samples. &lt;/li&gt;
&lt;li&gt;Implemented binding validation of hierarchical path notation. &lt;/li&gt;
&lt;li&gt;Fixed many bugs throughout the framework.&lt;/li&gt;
&lt;li&gt;Lots of other random features and improvements&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope that if you are building WPF or Silverlight applications you will take some time to evaluate &lt;a target="_blank" href="http://caliburn.codeplex.com/"&gt;Caliburn&lt;/a&gt; and give me some feedback.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=47896" width="1" height="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></item><item><title>geekSpeak on MVVM with WPF and Silverlight</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/06/10/geekspeak-on-mvvm-with-wpf-and-silverlight.aspx</link><pubDate>Wed, 10 Jun 2009 15:21:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:47807</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=47807</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/06/10/geekspeak-on-mvvm-with-wpf-and-silverlight.aspx#comments</comments><description>&lt;p&gt;Today at 3pm EDT/12pm PDT &lt;a href="http://devlicio.us/blogs/christopher_bennage/default.aspx"&gt;Christopher Bennage&lt;/a&gt; and I will be jabbering about MVVM and UI Architecture on the MSDN Webcast geekSpeak.&amp;nbsp; &lt;a target="_blank" href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032418083&amp;amp;EventCategory=4&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;Please join us!&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=47807" width="1" height="1"&gt;</description></item><item><title>MVVM and The Origins of Caliburn</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/05/18/mvvm-and-the-origins-of-caliburn.aspx</link><pubDate>Mon, 18 May 2009 14:51:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46880</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>8</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=46880</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/05/18/mvvm-and-the-origins-of-caliburn.aspx#comments</comments><description>&lt;p&gt;Recently &lt;a href="http://codebetter.com/blogs/glenn.block/archive/2009/05/04/view-model-the-movie-cast-your-vote.aspx"&gt;Glenn Block asked some questions of the community&lt;/a&gt; concerning what support Microsoft should offer for the MVVM design pattern in WPF/Silverlight.&amp;nbsp; I&amp;rsquo;d like to answer that question here, but in a round-about manner.&amp;nbsp; I&amp;rsquo;m going to use this as an opportunity to talk about the origins of Caliburn.&lt;/p&gt;
&lt;p&gt;About two years ago I entered &lt;a href="http://dotnetslackers.com/articles/wpf/WPFEnterpriseExampleWithRailsStyleUI.aspx"&gt;an article&lt;/a&gt; in a contest on &lt;a href="http://dotnetslackers.com/articles/wpf/WPFEnterpriseExampleWithRailsStyleUI.aspx"&gt;dotnetslackers&lt;/a&gt; about a prototype framework I had developed several months earlier during my free time.&amp;nbsp; The sample application for the article is manufactured, but the framework was built for a real application I was working on then.&amp;nbsp; At that time, I was writing a GUI test runner for &lt;a href="http://nspecify.sourceforge.net/"&gt;NSpecify&lt;/a&gt; framework.&amp;nbsp; I had been doing WPF development for over a year, though not for paying contracts (I built some really cool samples such as a WF designer, an interactive fiction viewer/editor, a partial implementation of the Office 2007 ribbon and &lt;a href="http://devlicio.us/blogs/christopher_bennage/archive/2006/11/09/game-programming-with-net-3-0.aspx"&gt;a multi player online game&lt;/a&gt;) and was using this project to experiment with some new architectural ideas.&amp;nbsp; I had long since become frustrated with the typical code-behind model and had been looking for ways to move away from it.&amp;nbsp; Being heavily influenced by &lt;a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx"&gt;John Gossman&amp;rsquo;s article&lt;/a&gt; on MVVM, I began making greater use of Commands to enable databinding of UI to actions.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the progression I went through and suspect that many WPF developers can identify with:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Started by manually wiring events and handling them in the code-behind. &lt;/li&gt;
&lt;li&gt;Factored logic out of the code-behind and into some sort of presentation class (Presenter, VM, etc).&amp;nbsp; Event handlers became a pass-through to methods on the presentation class. &lt;/li&gt;
&lt;li&gt;Moved away from events and towards commands.&amp;nbsp; Created custom commands that hung off the presentation class and were wired to the UI through databinding. &lt;/li&gt;
&lt;li&gt;Got tired of creating lots of commands after about 5 minutes and implemented a &lt;a href="http://mbrownchicago.spaces.live.com/blog/cns!2221DC39E0C749A4!596.entry?sa=68790789"&gt;DelegatingCommand pattern&lt;/a&gt; to enable databinding on the view side, with a pass-through to a standard method on the presentation class. &lt;/li&gt;
&lt;li&gt;Got tired of instantiating and wiring delegating commands after about 15 minutes and created a fluent interface dedicated to the task.&amp;nbsp; The code looked something like this:
&lt;pre name="code" class="csharp"&gt;public DelegatingCommand Save
{
    get { return Execute.AsCommand(DoSave).If(CanDoSave).Async(); }
}
&lt;/pre&gt;
In fact, you could see the implementation of this in some early versions of Caliburn. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To answer Glenn&amp;rsquo;s first question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Where does the platform help? Where does it hinder?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Even though the fluent interface is a pretty efficient way of binding models and views, it is still fairly limited in its capabilities.&amp;nbsp;&amp;nbsp; With commands you are limited to elements that implement ICommandSource only.&amp;nbsp; So, if you want to have code execute on a ListBox.SelectionChanged event, you have to revert back to events and code-behind.&amp;nbsp; You could try and rig something up by using InputBindings/CommandBindings which exist on all UI elements, but using gestures to simulate control-specific events is kludgey.&amp;nbsp; Furthermore, InputBindings/CommandBindings have limitations due to the fact that they either are not DependencyObjects or don&amp;rsquo;t implement DependencyProperties and cannot be bound as easily, thus you have to use some sort of static class mechanism.&amp;nbsp; Furthermore, commands can only have one parameter and RoutedCommands are terribly confusing and IMHO an overly complex solution to the problem.&amp;nbsp; All of this is a bit shady and quite round-about in general.&amp;nbsp; This leads me to a rather simple answer to Glenn&amp;rsquo;s second question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What can we do in the platform to make life easier?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What we really want to do is bind the view directly to the methods themselves.&amp;nbsp; It would be nice if we had a mechanism by which we could bind any .NET event, routed event, gesture or command with one consistent syntax.&lt;/p&gt;
&lt;p&gt;Caliburn&amp;rsquo;s implementation of RoutedMessaging and Actions is my attempt to solve this very problem in the OSS space.&amp;nbsp; Actions was the first feature I developed for Caliburn (although there are quite a few more now and many more to come) and it remains one of the most used.&amp;nbsp; Here&amp;rsquo;s a snippet from one of Caliburn&amp;rsquo;s sample apps, demonstrating some of the syntax:&lt;/p&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;Button Content=&amp;quot;Example 1&amp;quot;
    Message.Attach=&amp;quot;Divide(left.Text, right.Text) : DivideResult.Text&amp;quot; /&amp;gt;
&amp;lt;Button Content=&amp;quot;Example 2&amp;quot;
    Message.Attach=&amp;quot;[Event Click] = [Action Divide(left.Text, right.Text) : DivideResult.Text]&amp;quot; /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Both these snippets do the same thing, the second is just more explicit about the details.&amp;nbsp; Here&amp;rsquo;s what all this does:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wire up to the &amp;ldquo;Click&amp;rdquo; event (Caliburn determines this to be the default in Ex1) &lt;/li&gt;
&lt;li&gt;Send an &amp;ldquo;Action Message&amp;rdquo; whenever the &amp;ldquo;Click&amp;rdquo; event fires (again Caliburn knows that Actions are default in Ex1) &lt;/li&gt;
&lt;li&gt;When the action executes, take the Text properties of the controls with names &amp;ldquo;left&amp;rdquo; and &amp;ldquo;right&amp;rdquo; and pass those values as parameters to the &amp;ldquo;Divide&amp;rdquo; action (a method on a class). &lt;/li&gt;
&lt;li&gt;Perform type conversion on the parameters. &lt;/li&gt;
&lt;li&gt;Take the return value of the action and databind it back to the Text property of the control with its name set to &amp;ldquo;DivideResult&amp;rdquo; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This demonstrates binding directly to methods from events.&amp;nbsp; But you can also trigger actions based on an ICommandSource&amp;rsquo;s command execution:&lt;/p&gt;
&lt;pre name="code" class="xml"&gt;Message.Attach=&amp;quot;[CommandSource] = [Action Divide(left.Text, right.Text) : DivideResult.Text]&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Or by gesture:&lt;/p&gt;
&lt;pre name="code" class="xml"&gt;Message.Attach=&amp;quot;[Gesture MouseAction: LeftClick, Modifiers: Control] = [Action Divide(left.Text, right.Text) : DivideResult.Text]&amp;quot;
&lt;/pre&gt;
&lt;p&gt;The &amp;ldquo;trigger&amp;rdquo; aspect of Caliburn is completely pluggable.&amp;nbsp; In fact, the ICommandSource trigger implementation was a user submitted extension, much thanks to &lt;a href="http://www.linkedin.com/in/marcoamendola"&gt;Marco Amendola&lt;/a&gt;.&amp;nbsp; Additionally, you can plug the right part of the expression.&amp;nbsp; So instead of just triggering actions, you can also trigger commands (or anything you wish to extend it too):&lt;/p&gt;
&lt;pre name="code" class="xml"&gt;Message.Attach=&amp;quot;[Event SelectionChanged] = [ContainerCommand ShowMessage(title.Text, message.Text)]&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Caliburn can resolve commands from the container (ContainerCommand) , resource dictionaries (ResoureceCommand) or through databinding (BoundCommand) and the command&amp;rsquo;s trigger doesn&amp;rsquo;t have to be an ICommandSource nor is it limited to one parameter.&amp;nbsp; In fact, commands in Caliburn are built on top of actions.&amp;nbsp; Which means they inherit a host of other features as well, such as ASP.NET MVC-style rescues and filters (which are extensible) and extensible ActionResults (called IExecutableResult in Caliburn).&amp;nbsp; You can also decorate your action/command with an [Async] attribute and Caliburn will call it on a background thread, and automatically marshal the callback onto the UI thread (you even have control over the background task&amp;rsquo;s progress and cancellation).&lt;/p&gt;
&lt;p&gt;As a developer, it was really important to me that I have a consistent way of wiring user interactions to my model.&amp;nbsp; Furthermore, I wanted the same syntax for both WPF and Silverlight (and yes, that took a lot of work in SL2).&amp;nbsp; This brings me to a key point, whatever Microsoft builds, &lt;i&gt;the public API should be the same for both WPF and Silverlight&lt;/i&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What role do developers / designers play in your application of ViewModel?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think that the only way to have a strong UI is through iterative development.&amp;nbsp; This means constant communication between the development team and the client, but also constant communication between the developers and the designers.&amp;nbsp; Keep in mind that a View and its ViewModel are &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc947917.aspx"&gt;a highly cohesive unit&lt;/a&gt;.&amp;nbsp; This means that a designer is going influence what your ViewModel looks like.&amp;nbsp; What I would really like is a way for Views to be more easily bound to their ViewModels.&amp;nbsp; &lt;a href="http://devlicio.us/blogs/christopher_bennage/default.aspx"&gt;Christopher&lt;/a&gt; and I have often talked about how nice it would be for Caliburn to have a Cider/Expression plugin that let you wire views directly to the ViewModel (both properties and methods).&amp;nbsp; And that definitely describes something I would like to see from Microsoft in this area.&amp;nbsp; The next phase in designer/developer interaction in WPF and Silverlight is a ViewModel rather than code-behind centric tooling experience.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=46880" width="1" height="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/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category></item><item><title>Off to Mix!</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/03/16/off-to-mix.aspx</link><pubDate>Mon, 16 Mar 2009 12:16:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44994</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=44994</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/03/16/off-to-mix.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m heading out to &lt;a href="http://2009.visitmix.com/"&gt;Mix09&lt;/a&gt; in Las Vegas today.&amp;nbsp; If you are going to be there, please say hello.&amp;nbsp; I&amp;#39;m looking forward to meeting people and talking about &lt;a href="http://www.silverarcade.com/"&gt;one of my new projects&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44994" width="1" height="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/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category></item><item><title>The Caliburn Beta is Live</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/26/the-caliburn-beta-is-live.aspx</link><pubDate>Fri, 27 Feb 2009 02:15:51 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44697</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>17</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=44697</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/26/the-caliburn-beta-is-live.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/blogs/rob_eisenberg/Caliburnfull_495597F8.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;margin-left:0px;border-left-width:0px;margin-right:0px;" title="Caliburn-full" border="0" alt="Caliburn-full" align="left" src="http://devlicio.us/blogs/rob_eisenberg/Caliburnfull_thumb_3466A636.jpg" width="192" height="100" /&gt;&lt;/a&gt;Today is a long awaited day for me.&amp;#160; &lt;a href="http://www.codeplex.com/caliburn/Release/ProjectReleases.aspx?ReleaseId=23840" target="_blank"&gt;Caliburn is now in official Beta.&lt;/a&gt;&amp;#160; There have been many bug fixes and a ton of new features since the Alpha release last October.&amp;#160; We’ve also been dogfooding it on several projects, one of which is &lt;a href="http://www.nhprof.com/" target="_blank"&gt;NHProf&lt;/a&gt;.&amp;#160; I wanted to use this post as an opportunity to summarize Caliburn’s current feature set and introduce you to the Line-Of-Business sample provided with the framework, built with Caliburn and Silverlight.&lt;/p&gt;  &lt;p&gt;If you are in the WPF or Silverlight world, you may have spent some time trying to figure out how to cleanly architect a UI with these technologies.&amp;#160; You may have come across the MVVM pattern through excellent articles like &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx" target="_blank"&gt;this one by Josh Smith&lt;/a&gt; or you may have found more general UI architecture guidance in &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the-build-your-own-cab-series-table-of-contents.aspx" target="_blank"&gt;Jeremy Miller’s Build Your Own Cab series&lt;/a&gt; or on &lt;a href="http://martinfowler.com/eaaDev/SupervisingPresenter.html" target="_blank"&gt;Martin Fowler’s site&lt;/a&gt;.&amp;#160; Whatever the case, its obvious that building solid UI is difficult and there are a ton of patterns and variations on patterns geared to solving common problems.&amp;#160; The goal of Caliburn is to make building UI easier by providing a class library that eliminates the boiler-plate code often involved in implementing these solutions.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Features of the Beta&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Actions&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Actions extend the databinding capabilities of WPF/SL by enabling a UI to bind not only to data but to methods. Caliburn uses triggers to wire events, gestures, and attached events (extensible to any trigger type you can think of) to methods on a presentation-related class. This type of method binding removes much of the glue code involved in building an &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;MVC&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Model_View_Presenter"&gt;MVP&lt;/a&gt; architecture. Additionally, it enables very rich &lt;a href="http://martinfowler.com/eaaDev/PresentationModel.html"&gt;Presentation Model &lt;/a&gt;(MVVM) scenarios. In addition to basic execution of methods, Caliburn&amp;#39;s action mechanism can pass data from the UI into the methods as parameters and bind return values back to the UI (in fact the return behavior of action is entirely extensible by implementing a custom &lt;em&gt;IExecutableResult&lt;/em&gt;). A filter mechanism (similar to ASP.NET MVC) exists for decorating methods. Filters can affect the availability of a given action through the UI, which can be represented by automatically disabling, hiding or collapsing controls (extensible to any visualization). There are several built-in filters, but the mechanism is entirely extensible. Caliburn can also automatically execute methods asynchronously, and execute callbacks. It does all the thread marshalling for you.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Commands&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Caliburn&amp;#39;s command implementation is an alternative to WPF&amp;#39;s and supplies very useful functionality that is altogether missing from Silverlight. As you might expect, it is an implementation of the &lt;a href="http://en.wikipedia.org/wiki/Command_pattern"&gt;Command Pattern. &lt;/a&gt;. Commands are built on top of Actions and thus share many of the same features, including multiple input parameters, filters and automatic asynchronous execution. Additionally, commands can be created in hierarchies, such that a parent command can execute multiple child commands. The parent command&amp;#39;s availability can also be affected by its children in various ways. There are two types of composite commands available out of the box, but the mechanism is extensible. There is no limit to the depth of the command hierarchy.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;MVP &lt;/em&gt;and &lt;em&gt;Application Controller&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Two common patterns that occur in applications are &lt;a href="http://martinfowler.com/eaaDev/SupervisingPresenter.html" target="_blank"&gt;Supervising Controller&lt;/a&gt; and &lt;a href="http://martinfowler.com/eaaCatalog/applicationController.html" target="_blank"&gt;Application Controller&lt;/a&gt;.&amp;#160; Caliburn supports architectures based on these ideas directly through its various implementations of the &lt;em&gt;IPresenter&lt;/em&gt; interface.&amp;#160; Often times, these types of architectures involve tricky UI lifecycle issues such as handling activation, deactivation and shutdown semantics for various UI components.&amp;#160; The basic logic for handling these scenarios is found in Caliburn’s &lt;em&gt;Presenter&lt;/em&gt;, &lt;em&gt;PresenterManager&lt;/em&gt;, &lt;em&gt;MultiPresenterManager&lt;/em&gt; and &lt;em&gt;Navigator &lt;/em&gt;classes.&amp;#160; By composing these classes you can create a hierarchical model representing the entire runtime state of your application.&amp;#160; In Silverlight, you can even use the browser as an &lt;em&gt;Application Controller&lt;/em&gt; with Caliburn’s support for deep linking.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Presentation Model &lt;/em&gt;and&lt;em&gt; MVVM&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Caliburn also supplies a set of base classes that enable transactional editing, n-level undo/redo, dirty tracking and validation.&amp;#160; These classes are perfect for creating an editable &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx" target="_blank"&gt;ViewModel&lt;/a&gt; or representing the “Model” portion of the MVP triad when utilizing a &lt;a href="http://martinfowler.com/eaaDev/SupervisingPresenter.html" target="_blank"&gt;Supervising Controller&lt;/a&gt;.&amp;#160; This functionality is accomplished through a rich metadata-aware property system, similar to dependency properties, but more suited to the needs of a model rather than a view.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Testability&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;One of the goals of Caliburn is to make it easier to build applications right. To this effect, Caliburn has features geared around &lt;a href="http://en.wikipedia.org/wiki/Unit_test"&gt;unit testing&lt;/a&gt;. There is currently rich support for testing databindings in WPF and a simple fluent interface for verifying change notification on model objects.&amp;#160; Unit tests for view bindings give the developer the confidence they need to refactor their models, knowing that they will be aware of broken bindings before they run the application.&amp;#160; Not only will they be aware that the bindings are broken, but Caliburn’s binding validator will tell you exactly where the problem is in the UI hierarchy and what the specific error was.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Many, many more features…&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;LOB Sample Application&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In addition to the framework, you will find several samples as part of the Beta download.&amp;#160; The most thorough demonstration of Caliburn can be found in the Silverlight Contact Manager sample.&amp;#160; Some features you can look for are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Dependency injection is used throughout. &lt;/li&gt;    &lt;li&gt;Use of Actions throughout (this includes the use of Preview and Dependencies filters). &lt;/li&gt;    &lt;li&gt;The ContactDetailsPresenter.ValidateContact demonstrates the use of a custom IExecutableResult from an Action.      &lt;ul&gt;       &lt;li&gt;When you mouse over the &amp;#39;red dot&amp;#39; after changing a contact, a popup will appear.&amp;#160; That is the result of the IExecutableResult. &lt;/li&gt;        &lt;li&gt;IExecutableResult works in conjunction with a custom ValidationResult. &lt;/li&gt;        &lt;li&gt;If you have some invalid properties, you can click on notices in the popup to focus the control related to the error. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/blogs/rob_eisenberg/IExecutableResult_28D0E8F7.jpg"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="IExecutableResult" border="0" alt="IExecutableResult" src="http://devlicio.us/blogs/rob_eisenberg/IExecutableResult_thumb_5D05123D.jpg" width="611" height="328" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The structure of the application forms a composite hierarchy with implementers of IPresenter.&amp;#160; This hierarchy exists at runtime.&amp;#160; Below is an example of what might occur:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ShellPresenter (PresenterManager)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -&amp;gt; ContactListPresenter (MultiPresenterManager)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -&amp;gt; N of ContactDetailsPresenter (Presenter) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/blogs/rob_eisenberg/composite_541810AF.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="composite" border="0" alt="composite" src="http://devlicio.us/blogs/rob_eisenberg/composite_thumb_4F355CF3.jpg" width="611" height="376" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;*The red, blue and green outlines show the views bound to the composited presenters.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The application controller pattern is used as a top level coordinator. &lt;/li&gt;    &lt;li&gt;Deep linking is accomplished with the DeepLinkStateManager.&amp;#160; &lt;/li&gt;    &lt;li&gt;The Settings class builds on top of the IsolatedStorageStateManager for simple key/value pairs stored locally. &lt;/li&gt;    &lt;li&gt;The Model classes inherit from ModelBase and uses a special form of property declaration (similar to dependency properties).&amp;#160; By nature of this form of definition, these classes gain the following features:      &lt;ul&gt;       &lt;li&gt;Transactional editing support (BeginEdit, EndEdit, CancelEdit)&amp;#160; &lt;/li&gt;        &lt;li&gt;Property change notification &lt;/li&gt;        &lt;li&gt;Dirty tracking &lt;/li&gt;        &lt;li&gt;Validation &lt;/li&gt;        &lt;li&gt;N-Level Undo/Redo support &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Advanced shutdown scenarios for presenters. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/blogs/rob_eisenberg/shutdown_4A52A937.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="shutdown" border="0" alt="shutdown" src="http://devlicio.us/blogs/rob_eisenberg/shutdown_thumb_658B0238.jpg" width="611" height="654" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In addition to Caliburn&amp;#39;s framework, this sample demonstrates an application specific framework built on top of Caliburn, to add more convention to the way this app is built. Examples of this include: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Use of the ViewAttribute in conjunction the ViewZone to detect presenter&amp;#39;s views, display them and wire up Action.Target. &lt;/li&gt;    &lt;li&gt;Use of a custom set of attached properties (Bind...) to do some fancy wire up of data binding, validation, etc. &lt;/li&gt;    &lt;li&gt;Use of the HistoryKey/HistoryInfo to aid the DeepLinkStateManager. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Finally, there are a number of other useful SL tidbits built in as well: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Visual transitions with the TransitionPresenter and implementors of ITransition. &lt;/li&gt;    &lt;li&gt;Modal dialogs &lt;/li&gt;    &lt;li&gt;Data bound tooltips. &lt;/li&gt;    &lt;li&gt;UI scaling (ala ViewBox) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I hope this helps in your overall understanding of Caliburn and serves as an example of UI architecture.&amp;#160; Feedback is welcome.&amp;#160; Enjoy the new release and have a look at the &lt;a href="http://caliburn.codeplex.com/Wiki/View.aspx?title=Table%20Of%20Contents&amp;amp;referringTitle=Home" target="_blank"&gt;growing developer documentation&lt;/a&gt;!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44697" width="1" height="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></item><item><title>I Finally Sold Out to Twitter</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/19/i-finally-sold-out-to-twitter.aspx</link><pubDate>Thu, 19 Feb 2009 18:37:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44390</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=44390</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/19/i-finally-sold-out-to-twitter.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://twitter.com/EisenbergEffect"&gt;http://twitter.com/EisenbergEffect&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Now I&amp;#39;m in with the hipsters... Let&amp;#39;s hope I can still get some work done.&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44390" width="1" height="1"&gt;</description></item><item><title>A MEF Misunderstanding</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/05/a-mef-misunderstanding.aspx</link><pubDate>Thu, 05 Feb 2009 19:13:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44014</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=44014</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/05/a-mef-misunderstanding.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/04/mef-iservicelocator-and-caliburn.aspx"&gt;Yesterday &lt;/a&gt;I wrote about integrating &lt;a href="http://www.codeplex.com/caliburn"&gt;Caliburn &lt;/a&gt;and &lt;a href="http://www.codeplex.com/MEF"&gt;MEF &lt;/a&gt;along with getting things to work with &lt;a href="http://www.codeplex.com/CommonServiceLocator"&gt;IServiceLocator&lt;/a&gt;.&amp;nbsp; I had a feeling that I was going about things all wrong and was eagerly hoping for some constructive criticism.&amp;nbsp; &lt;a href="http://codebetter.com/blogs/glenn.block/"&gt;Glenn Block&lt;/a&gt; was kind enough to engage with me on the subject and has agreed to publish a proper implementation of &lt;a href="http://www.codeplex.com/CommonServiceLocator"&gt;IServiceLocator &lt;/a&gt;for &lt;a href="http://www.codeplex.com/MEF"&gt;MEF&lt;/a&gt;.&amp;nbsp; Keep an eye on &lt;a href="http://codebetter.com/blogs/glenn.block/"&gt;his blog&lt;/a&gt; for that (and certainly don&amp;#39;t use my poo poo code) .&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44014" width="1" height="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/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MEF/default.aspx">MEF</category></item><item><title>MEF, IServiceLocator and Caliburn</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/04/mef-iservicelocator-and-caliburn.aspx</link><pubDate>Wed, 04 Feb 2009 22:12:48 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43993</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=43993</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/02/04/mef-iservicelocator-and-caliburn.aspx#comments</comments><description>&lt;p&gt;My company just began working on a large, modular WPF project.&amp;#160; I’ve been doing some research and recently took some time to dig into the &lt;a href="http://www.codeplex.com/MEF" target="_blank"&gt;Managed Extensibility Framework (MEF)&lt;/a&gt;.&amp;#160; I’m quite impressed with the direction that the project is going.&amp;#160; MEF is going to fulfill our modularity needs quite well.&lt;/p&gt;  &lt;p&gt;At the same time, I have refactored &lt;a href="http://www.codeplex.com/caliburn" target="_blank"&gt;Caliburn&lt;/a&gt; to use the &lt;a href="http://www.codeplex.com/CommonServiceLocator" target="_blank"&gt;CommonServiceLocator&lt;/a&gt; that P&amp;amp;P released last year.&amp;#160; Caliburn is a loosely coupled set of UI services and requires dependency injection to work.&amp;#160; I have IServiceLocator implementations of &lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt;Windsor&lt;/a&gt;, &lt;a href="http://structuremap.sourceforge.net/Default.htm" target="_blank"&gt;StructureMap&lt;/a&gt;, &lt;a href="http://www.codeplex.com/unity" target="_blank"&gt;Unity&lt;/a&gt; and &lt;a href="http://www.springframework.net/" target="_blank"&gt;Spring.NET&lt;/a&gt;.&amp;#160; Many of these implementations are based on the adapter code that can be found on the &lt;a href="http://www.codeplex.com/CommonServiceLocator" target="_blank"&gt;CommonServiceLocator site&lt;/a&gt;.&amp;#160; Interestingly, there isn’t an implementation of IServiceLocator for MEF.&lt;/p&gt;  &lt;p&gt;As my current project needs MEF to solve modularity concerns and Caliburn to solve UI architecture issues, I spent some time today writing an IServiceLocator adapter for MEF.&amp;#160; It turned out not to be too difficult, but the code is not pretty.&amp;#160; This stems from the fact that MEF’s CompositionContainer is generics based, but ServiceLocatorImplBase uses Type instances.&amp;#160; I had to resort to using reflection to interact with the underlying container.&amp;#160; I’m going to post the code below so that you can see how to do this sort of thing, but also in hopes that someone like &lt;a href="http://codebetter.com/blogs/glenn.block/default.aspx" target="_blank"&gt;Glenn&lt;/a&gt; can correct any stupid stuff ;)&amp;#160; (I was hoping there is a non-reflection-based mechanism that I just didn’t see.)&lt;/p&gt;  &lt;p&gt;In addition to implementing IServiceLocator, Caliburn needs a way to inform the container of its own components.&amp;#160; In Caliburn you do this by either implementing IConfigurator or by providing a delegate which can take Caliburn’s ComponentInfo and register the services appropriately with the container.&amp;#160; This is where the real MEF challenge comes in.&amp;#160; MEF is not &lt;em&gt;exactly&lt;/em&gt; a DI container, and thus doesn’t have the typical registration mechanism that you might expect.&amp;#160; I wasn’t really sure what the best way to solve this problem was, so I implemented my own ComposablePart.&amp;#160; Below is the entire MEFAdapter which implements both IServiceLocator and IConfigurator.&amp;#160; I would appreciate feedback from any MEF experts or members of the MEF team.&amp;#160; Much thanks in advance!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;MEFAdapter&lt;/strong&gt;&lt;/p&gt;  &lt;pre class="c#:nogutter:nocontrols" name="code"&gt;using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using Caliburn.Core;
using Microsoft.Practices.ServiceLocation;

namespace Caliburn.MEF
{
    public class MEFAdapter : ServiceLocatorImplBase, IConfigurator
    {
        private readonly CompositionContainer _container;
        private readonly MethodInfo _getExportedObjectByType;
        private readonly MethodInfo _getExportedObjectByTypeAndKey;
        private readonly MethodInfo _getExportedObjectsByType;

        public MEFAdapter(CompositionContainer container)
        {
            _container = container;

            _getExportedObjectByType = _container.GetType().GetMethod(&amp;quot;GetExportedObject&amp;quot;, Type.EmptyTypes);
            _getExportedObjectByTypeAndKey = _container.GetType().GetMethod(&amp;quot;GetExportedObject&amp;quot;, new[] { typeof(string) });
            _getExportedObjectsByType = _container.GetType().GetMethod(&amp;quot;GetExportedObjects&amp;quot;, Type.EmptyTypes);
        }

        protected override object DoGetInstance(Type serviceType, string key)
        {
            MethodInfo genericMethod;

            if(!string.IsNullOrEmpty(key))
            {
                genericMethod = _getExportedObjectByTypeAndKey.MakeGenericMethod(serviceType);
                return genericMethod.Invoke(_container, new[] { key });
            }

            genericMethod = _getExportedObjectByType.MakeGenericMethod(serviceType);
            return genericMethod.Invoke(_container, null);
        }

        protected override IEnumerable&amp;lt;object&amp;gt; DoGetAllInstances(Type serviceType)
        {
            MethodInfo genericMethod = _getExportedObjectsByType.MakeGenericMethod(serviceType);
            var results = (IEnumerable)genericMethod.Invoke(_container, null);

            foreach(var result in results)
            {
                yield return result;
            }
        }

        public void ConfigureWith(IEnumerable&amp;lt;ComponentInfo&amp;gt; components)
        {
            var batch = new CompositionBatch();

            foreach(var componentInfo in components)
            {
                batch.AddPart(new ComponentPart(componentInfo));
            }

            _container.Compose(batch);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;ComponentPart&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="c#:nogutter:nocontrols" name="code"&gt;using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Reflection;
using Caliburn.Core;

namespace Caliburn.MEF
{
    public class ComponentPart : ComposablePart
    {
        private readonly ComponentInfo _info;
        private readonly List&amp;lt;ImportDefinition&amp;gt; _imports = new List&amp;lt;ImportDefinition&amp;gt;();
        private readonly ExportDefinition[] _exports;
        private readonly Dictionary&amp;lt;ImportDefinition, Export&amp;gt; _satisfiedImports = new Dictionary&amp;lt;ImportDefinition, Export&amp;gt;();
        private object _cachedInstance;
        private readonly ConstructorInfo _greedyConstructor;

        public ComponentPart(ComponentInfo info)
        {
            _info = info;

            _greedyConstructor = (from c in info.Implementation.GetConstructors()
                                  orderby c.GetParameters().Length descending
                                  select c).FirstOrDefault();

            if (_greedyConstructor != null)
            {
                foreach (var parameterInfo in _greedyConstructor.GetParameters())
                {
                    var parameterType = parameterInfo.ParameterType;

                    var import = new ImportDefinition(
                        def =&amp;gt; def.ContractName == parameterType.FullName,
                        ImportCardinality.ExactlyOne,
                        false,
                        true
                        );

                    _imports.Add(import);
                }
            }

            string contractName = info.Key is string ? info.Key.ToString() : ((Type)info.Key).FullName;

            var export = new ExportDefinition(
                contractName,
                null
                );

            _exports = new[] {export};
        }

        public override object GetExportedObject(ExportDefinition definition)
        {
            if (_info.Lifetime == ComponentLifetime.PerRequest)
                return CreateInstance(definition);

            if(_cachedInstance == null)
                _cachedInstance = CreateInstance(definition);

            return _cachedInstance;
        }

        private object CreateInstance(ExportDefinition definition)
        {
            var args = new List&amp;lt;object&amp;gt;();

            if(_greedyConstructor != null)
            {
                foreach(var parameterInfo in _greedyConstructor.GetParameters())
                {
                    var arg = (from export in _satisfiedImports.Values
                               where export.Definition.ContractName == parameterInfo.ParameterType.FullName
                               select export).FirstOrDefault();

                    args.Add(arg.GetExportedObject());
                }
            }

            return args.Count &amp;gt; 0
                       ? Activator.CreateInstance(_info.Implementation, args.ToArray())
                       : Activator.CreateInstance(_info.Implementation);
        }

        public override void SetImport(ImportDefinition definition, IEnumerable&amp;lt;Export&amp;gt; exports)
        {
            _satisfiedImports[definition] = exports.FirstOrDefault();
        }

        public override IEnumerable&amp;lt;ExportDefinition&amp;gt; ExportDefinitions
        {
            get { return _exports; }
        }

        public override IEnumerable&amp;lt;ImportDefinition&amp;gt; ImportDefinitions
        {
            get { return _imports; }
        }
    }
}&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43993" width="1" height="1"&gt;</description></item><item><title>Caliburn V1 Roadmap</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/29/caliburn-v1-roadmap.aspx</link><pubDate>Thu, 29 Jan 2009 22:56:40 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43906</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=43906</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/29/caliburn-v1-roadmap.aspx#comments</comments><description>&lt;p&gt;I’ve been working hard on Caliburn in my spare time, gearing up for the V1 release.&amp;#160; In the next two weeks, you can expect to see an official Beta 1.&amp;#160; The beta should be pretty solid and feature rich.&amp;#160; After the beta I’m not planning on any major feature additions, just bug fixes and usability improvements depending on the feedback I get from users.&amp;#160; It is my desire to see version one released sometime prior to Mix09 in March. &lt;/p&gt;  &lt;p&gt;Things that are coming in Beta 1 and are already in the trunk include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A data binding validation api designed for use in unit tests.&lt;/li&gt;    &lt;li&gt;A series of base classes for representing and managing various flavors of the MVP pattern as well as navigation scenarios. (This includes history/back button support in Silverlight).&lt;/li&gt;    &lt;li&gt;A series of base classes for creating models that support transactional editing, dirty tracking, validation and undo/redo support.&amp;#160; These models can be used to build up an editable ViewModel.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As of today there are over 400 unit tests for Caliburn and I will be adding more during the next weeks and after the beta.&lt;/p&gt;  &lt;p&gt;There are a few things left to do before I release an official beta.&amp;#160; They are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Create a sample application demonstrating the MVP classes and the transactional model support.&lt;/li&gt;    &lt;li&gt;Write documentation for the above features, based on the sample application.&lt;/li&gt;    &lt;li&gt;Incorporate the CommonServiceLocator into Caliburn and refactor the code appropriately.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Post beta, I am thinking about the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Implementing a container adapter for MEF.&lt;/li&gt;    &lt;li&gt;Implementing some container adapters for Silverlight.&lt;/li&gt;    &lt;li&gt;Fixing bugs&lt;/li&gt;    &lt;li&gt;Adding more unit tests.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That’s the plan!&amp;#160; Let’s see if we can make it happen.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43906" width="1" height="1"&gt;</description></item><item><title>Tampa TDD Firestarter This Saturday!</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/15/tampa-tdd-firestarter-this-saturday.aspx</link><pubDate>Thu, 15 Jan 2009 18:52:44 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43761</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=43761</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/15/tampa-tdd-firestarter-this-saturday.aspx#comments</comments><description>&lt;p&gt;From the Event Site:&lt;/p&gt;  &lt;p&gt;Software is continually growing in complexity. What is needed for every team is a method to discover defects and bugs as soon as they are added to the system rather than after the software ships. An ongoing documentation system that is tied directly to your codebase is just as useful.&lt;/p&gt;  &lt;p&gt;Test Driven Development aims to ease the pain of changes to your codebase as well as providing a safety net for any changes made to the system. You can easily run your test suite to find errors that were introduced to the system by a modification to the code. Tests also allow you to continually re-factor your codebase and thus create a more flexible, cohesive codebase.&lt;/p&gt;  &lt;p&gt;In this day- long event, you will go from start to finish with a sample domain problem and how to write tests to drive functionality of the system. To accommodate existing TDD enthusiasts, we will be providing a beginner and intermediate tracks at the same time. There will be hour long presentations at the end of the day that will reinforce what you have learned during the day with surrounding practices.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Saturday, January 17, 2009&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;9:00 AM&amp;#8211;5:00PM&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032397083&amp;amp;culture=en-US"&gt;Click here to register&lt;/a&gt; or call (877) 673-8368 with event ID 1032397083&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Speakers include &lt;a href="http://www.cornetdesign.com/"&gt;Cory Foy&lt;/a&gt;, &lt;a href="http://scottcreynolds.lostechies.com/"&gt;Scott C. Reynolds&lt;/a&gt;, &lt;a href="http://schambers.lostechies.com/"&gt;Sean Chambers&lt;/a&gt;, &lt;a href="http://devlicio.us/blogs/christopher_bennage/default.aspx"&gt;Christopher Bennage&lt;/a&gt; and &lt;a href="http://devlicio.us/blogs/rob_eisenberg"&gt;myself&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43761" width="1" height="1"&gt;</description></item><item><title>WebForms Developer Wanted</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/06/webforms-developer-wanted.aspx</link><pubDate>Tue, 06 Jan 2009 21:21:11 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43654</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=43654</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/06/webforms-developer-wanted.aspx#comments</comments><description>&lt;p&gt;My company is looking for an experienced WebForms developers to take ownership of one of our small projects.&amp;#160; The client has a need for new features and technical advice about every four to six months and this would provide an opportunity for an interested developer to make a few extra dollars on the side.&lt;/p&gt;  &lt;p&gt;A few interesting tidbits about the project:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Originally built with .NET 1.1 but was recently updated to .NET 3.5 and VS2008, so future modifications can take advantage to the latest language and platform features.&lt;/li&gt;    &lt;li&gt;A media focused application with potential for Silverlight additions in the near future.&lt;/li&gt;    &lt;li&gt;Built on a custom ORM.&amp;#160; (Has a small and simple domain model).&lt;/li&gt;    &lt;li&gt;Has been in production for about 3.5 years.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The client is located in St. Petersburg, FL, so if you are close, that&amp;#39;s a bonus, but it is not necessary.&amp;#160; If you are interested, please email me a resume.&amp;#160; Looking forward to hearing from you!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43654" width="1" height="1"&gt;</description></item><item><title>NH Prof Public Beta</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/02/nh-prof-public-beta.aspx</link><pubDate>Fri, 02 Jan 2009 16:01:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43584</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=43584</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/02/nh-prof-public-beta.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/blogs/christopher_bennage/default.aspx"&gt;Christoper &lt;/a&gt;and I have had the privelage of helping &lt;a href="http://ayende.com/Blog/archive/2009/01/02/nh-prof-is-in-public-beta.aspx"&gt;Ayende &lt;/a&gt;to build the UI for his NHibernate Profiler over the last couple months.&amp;nbsp; Yesterday evening he released the public beta with a 30 day trial version.&amp;nbsp; If you are using NHibernate, get over to &lt;a href="http://nhprof.com/"&gt;the product site&lt;/a&gt; and &lt;a href="http://nhprof.com/Download"&gt;download the beta&lt;/a&gt;.&amp;nbsp; This is going to be an invaluable tool for developers using NHibernate and you can get it at a special price if you purchase during the beta period.&lt;/p&gt;&lt;p&gt;As a developer on this project, I had the unique opportunity to watch &lt;a href="http://ayende.com/Blog/Default.aspx"&gt;a master&lt;/a&gt; at his craft.&amp;nbsp; The architecture of the product is clean and Ayende has managed to jam pack this version with a ton of NHibernate smarts.&amp;nbsp; Just working on it, I gained a deeper understanding of the types of problems one can run into while using an ORM.&amp;nbsp; I would not want to do another project without it.&lt;/p&gt;&lt;p&gt;Another exciting aspect of this application is that we are using the latest version of &lt;a href="http://www.codeplex.com/caliburn"&gt;Caliburn &lt;/a&gt;in the UI architecture.&amp;nbsp; Generally speaking, the UI architecture is composed of a very rich Presentation Model (MVVM) with a splash of MVP for good measure.&amp;nbsp; There is almost no code-behind in the views.&amp;nbsp; All communication is handled by Caliburn&amp;#39;s &lt;a href="http://www.codeplex.com/caliburn/Wiki/View.aspx?title=Table%20Of%20Contents"&gt;action message&lt;/a&gt; mechanism.&amp;nbsp; We were also able to use Caliburn&amp;#39;s new &lt;a href="http://www.codeplex.com/caliburn/Wiki/View.aspx?title=Table%20Of%20Contents"&gt;testability features&lt;/a&gt; to cover all our views with data binding validation tests and do basic property change notification testing.&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43584" width="1" height="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/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category></item><item><title>MVP Goodness!</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/01/mvp-goodness.aspx</link><pubDate>Thu, 01 Jan 2009 15:54:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43575</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=43575</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/01/01/mvp-goodness.aspx#comments</comments><description>&lt;p&gt;Congratulations to &lt;a href="http://devlicio.us/blogs/christopher_bennage/default.aspx"&gt;Christopher Bennage&lt;/a&gt; for receiving a 2009 MVP for Client App Dev!&amp;nbsp; Microsoft was also gracious enough to award me with an MVP in the same area!&amp;nbsp; Let the good times roll...&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43575" width="1" height="1"&gt;</description></item></channel></rss>
