<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Paulo Morgado : SCSF</title><link>http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx</link><description>Tags: SCSF</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>A new phase for the Acropolis project</title><link>http://msmvps.com/blogs/paulomorgado/archive/2007/11/04/a-new-phase-for-the-acropolis-project.aspx</link><pubDate>Sun, 04 Nov 2007 00:36:01 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1281166</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=1281166</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=1281166</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2007/11/04/a-new-phase-for-the-acropolis-project.aspx#comments</comments><description>&lt;p&gt;The &lt;a title="Acropolis Team Blog" href="http://blogs.msdn.com/acropolis/" target="_blank"&gt;Acropolis Team&lt;/a&gt; has &lt;a title="A new phase for the Acropolis project" href="http://blogs.msdn.com/acropolis/archive/2007/10/29/An-Acropolis-Update.aspx" target="_blank"&gt;announced&lt;/a&gt; that Acropolis is going to enter a new phase.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1281166" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WPF/default.aspx">WPF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/PnP/default.aspx">PnP</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftwareFactories/default.aspx">SoftwareFactories</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WindowsClient/default.aspx">WindowsClient</category></item><item><title>David S. Platt Has Posted An Event Visualizer for CAB</title><link>http://msmvps.com/blogs/paulomorgado/archive/2007/05/21/david-s-platt-has-posted-an-event-visualizer-for-cab.aspx</link><pubDate>Mon, 21 May 2007 21:50:21 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:917580</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=917580</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=917580</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2007/05/21/david-s-platt-has-posted-an-event-visualizer-for-cab.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.rollthunder.com/" target="_blank"&gt;David S. Platt&lt;/a&gt; has &lt;a title="Feature Article: An Event Visualizer for CAB" href="http://www.rollthunder.com/newsletter/newslv8n3.htm#Feature%20Article" target="_blank"&gt;posted&lt;/a&gt; an Event Visualizer for CAB. I&amp;#39;ll have to check it out.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=917580" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/PnP/default.aspx">PnP</category></item><item><title>Smart Client Software Factory - May 2007 Release is Live</title><link>http://msmvps.com/blogs/paulomorgado/archive/2007/05/20/smart-client-software-factory-may-2007-release-is-live.aspx</link><pubDate>Sun, 20 May 2007 11:35:27 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:914802</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=914802</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=914802</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2007/05/20/smart-client-software-factory-may-2007-release-is-live.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;(From&amp;nbsp;&lt;a title="Blaine Wastell - patterns &amp;amp; practices client architecture guidance" href="http://blogs.msdn.com/blaine/default.aspx" target="_blank"&gt;Blaine Wastell&lt;/a&gt;&amp;#39;s&amp;nbsp;&lt;a title="Smart Client Software Factory - May 2007 Release is Live" href="http://blogs.msdn.com/blaine/archive/2007/05/19/smart-client-software-factory-may-2007-release-is-live.aspx" target="_blank"&gt;post&lt;/a&gt; and &lt;a title="Mariano Szklanny&amp;#39; Blog" href="http://fdaction:?fdactionkey=632qP7CRnr&amp;amp;action=gotofeedlink&amp;amp;feedId=D900585E-C489-43F8-B963-87DC0CCC788E" target="_blank"&gt;Mariano Szklanny&lt;/a&gt;&amp;#39;s&amp;nbsp;&lt;a title="Smart Client Software Factory v2 shipped!" href="http://staff.southworks.net/blogs/mariano/archive/2007/05/19/Smart-Client-Software-Factory-v2-shipped_2100_.aspx" target="_blank"&gt;post&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;You can now download the&amp;nbsp;&lt;a title="Smart Client Software Factory - May 2007" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=2B6A10F9-8410-4F13-AD53-05A202FBDB63&amp;amp;displaylang=en" target="_blank"&gt;SCSF - May 2007 release&lt;/a&gt;. The new release provides support for .NET 3.0. The release is propagating to the download servers and&amp;nbsp;should be available when you read this. If not, be patient and&amp;nbsp;try a little later.&lt;/p&gt; &lt;p&gt;The release provides:  &lt;ul&gt; &lt;li&gt;&lt;em&gt;Windows Presentation Foundation interoperability CAB extensions&amp;nbsp; and View with presenter recipe (&lt;/em&gt;don&amp;#39;t miss &lt;a title="WPF Support in SCSF" href="http://staff.southworks.net/blogs/msaez/archive/2007/04/29/WPF-Support-in-SCSF.aspx" target="_blank"&gt;this post&lt;/a&gt; from &lt;a title="Miguel Saez&amp;#39;s Blog" href="http://staff.southworks.net/msaez" target="_blank"&gt;Miguel Saez&lt;/a&gt;&amp;nbsp;for more details&lt;em&gt;)&lt;/em&gt;  &lt;li&gt;&lt;em&gt;Offline application blocks and recipes; the application blocks support asynchronous calls to WCF web services. &lt;/em&gt; &lt;li&gt;&lt;em&gt;Richer ClickOnce Deployment capabilities &lt;/em&gt; &lt;li&gt;&lt;em&gt;Enhanced guidance packages which includes&amp;nbsp;code generation Visual Basic .NET 2005&amp;nbsp;&lt;/em&gt;(don&amp;#39;t miss &lt;a href="http://staff.southworks.net/blogs/jarguello/archive/2007/03/22/Smart-Client-Guidance-development.aspx"&gt;this post&lt;/a&gt; from &lt;a title="Juan Arguello&amp;#39;s Blog" href="http://staff.southworks.net/blogs/jarguello/default.aspx" target="_blank"&gt;Juan Arguello&lt;/a&gt; for more details)  &lt;li&gt;&lt;em&gt;Improved installation with a new dependency checker&lt;/em&gt;&lt;/li&gt; &lt;li&gt;&lt;em&gt;Compatibility with Enterprise Library 3.1.&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;a title="Installing the Smart Client Software Factory" href="http://www.codeplex.com/smartclient/Wiki/View.aspx?title=Installing%20the%20Smart%20Client%20Software%20Factory&amp;amp;referringTitle=Smart%20Client%20Software%20Factory" target="_blank"&gt;Here&lt;/a&gt; are instructions to install the&amp;nbsp;factory. The team has created a new &lt;a title="Getting Started with the Smart Client Software Factory" href="http://www.codeplex.com/smartclient/Wiki/View.aspx?title=Getting%20Started%20with%20the%20Smart%20Client%20Software%20Factory&amp;amp;referringTitle=Smart%20Client%20Software%20Factory" target="_blank"&gt;Getting Starting&lt;/a&gt; topic&amp;nbsp;on Codeplex. This&amp;nbsp;topic&amp;nbsp;includes instructions to create a Hello World Application with the factory.  &lt;p&gt;Check it out and let them know how you like it.  &lt;p&gt;And this means that the team is going to start it&amp;#39;s work on the &lt;a title="patterns &amp;amp; practices - Web Client Software Factory" href="http://www.codeplex.com/websf" target="_blank"&gt;Web Client Software Factory&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=914802" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Community/default.aspx">Community</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Tools/default.aspx">Tools</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/VisualStudio/default.aspx">VisualStudio</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WPF/default.aspx">WPF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/PnP/default.aspx">PnP</category></item><item><title>An Hierarchical CAB WorkItem Activation Service</title><link>http://msmvps.com/blogs/paulomorgado/archive/2006/11/04/An-Hierarchical-CAB-WorkItem-Activation-Service.aspx</link><pubDate>Sat, 04 Nov 2006 22:15:34 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:247300</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=247300</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=247300</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2006/11/04/An-Hierarchical-CAB-WorkItem-Activation-Service.aspx#comments</comments><description>&lt;p&gt;The application I'm currently working on has a rather complex UI. It's something like two tabbed work spaces and an outlook-like work space, that make one workspace by itself, that can have several instances inside another tabbed workspace, that can have several instances inside another tabbed workspace. Imagine something like&amp;nbsp;Visual Studio, inside a tab.&lt;/p&gt; &lt;p&gt;Each work space is controlled by its own work item and the same goes to every smart part.&lt;/p&gt; &lt;p&gt;With a UI like this, the work item activation service supplied by the &lt;a title="Composite UI Application Block" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp" target="_blank"&gt;CAB&lt;/a&gt; is of no use for me because I need to know what is the active work item at various levels.&lt;/p&gt; &lt;p&gt;What I came up with to solve my problem is the following implementation of the work item activation service:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; HierarchicalWorkItemActivationService : IWorkItemActivationService
{
&lt;span style="color:#0000ff;"&gt;    private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; syncroot = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;();
&lt;span style="color:#0000ff;"&gt;    private&lt;/span&gt; WorkItem activeWorkItem;
&lt;span style="color:#0000ff;"&gt;    private&lt;/span&gt; WorkItem hostingWorkItem;

    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; HierarchicalWorkItemActivationService()
    {
    }

    [ServiceDependency]
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; WorkItem HostingWorkItem
    {
        &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;
        {
            Debug.Assert(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentNullException("&lt;span style="color:#8b0000;"&gt;value&lt;/span&gt;");
            }
            Debug.Assert(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.hostingWorkItem == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.hostingWorkItem != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InvalidOperationException("&lt;span style="color:#8b0000;"&gt;HostingWorkItem already set.&lt;/span&gt;");
            }
            &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.hostingWorkItem = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;
        }
    }

&lt;span style="color:#0000ff;"&gt;    public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ChangeStatus(WorkItem item)
    {
&lt;span style="color:#0000ff;"&gt;&lt;font color="#333333"&gt;&lt;span style="color:#0000ff;"&gt;&lt;font color="#333333"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color:#0000ff;"&gt;&lt;font color="#333333"&gt;&lt;/font&gt;&lt;/span&gt;        lock&lt;/span&gt; (syncroot)
        {
&lt;span style="color:#0000ff;"&gt;            if&lt;/span&gt; (item == &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.hostingWorkItem)
            {
                WorkItem hostingParentWorkItem = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.hostingWorkItem.Parent;
                &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (hostingParentWorkItem != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
                {
                    IWorkItemActivationService parentWorkItemActivationService = hostingParentWorkItem.Services.Get&amp;lt;IWorkItemActivationService&amp;gt;();
                    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (parentWorkItemActivationService != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
                    {
                        parentWorkItemActivationService.ChangeStatus(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.hostingWorkItem);
                    }
                }
            }
            &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;
            {
                &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (item.Status == WorkItemStatus.Active)
                {
                    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (item != &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activeWorkItem)
                    {
                        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activeWorkItem != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activeWorkItem.Status != WorkItemStatus.Terminated)
                        {
                            &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activeWorkItem.Deactivate();

                            &lt;span style="color:#008000;"&gt;// If the activeWorkItem is still active deactivates the item and aborts.&lt;/span&gt;
                            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activeWorkItem.Status == WorkItemStatus.Active)
                            {
                                item.Deactivate();
                                &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;
                            }
                        }
                        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activeWorkItem = item;
                    }
                }
            }
        }
    }
}
&lt;/pre&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=247300" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Community/default.aspx">Community</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category></item><item><title>Unit Testing With CAB</title><link>http://msmvps.com/blogs/paulomorgado/archive/2006/11/03/Unit-Testing-With-CAB.aspx</link><pubDate>Fri, 03 Nov 2006 09:02:41 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:241738</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=241738</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=241738</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2006/11/03/Unit-Testing-With-CAB.aspx#comments</comments><description>&lt;p&gt;For those who like to unit test their software and are developing &lt;a title="Composite UI Application Block" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp" target="_blank"&gt;CAB&lt;/a&gt; applications, the &lt;a title="Smart Client Software Factory" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp" target="_blank"&gt;SCSF&lt;/a&gt; comes&amp;nbsp;with&amp;nbsp;sample applications with&amp;nbsp;unit tests. These unit tests&amp;nbsp;are built on top of an&amp;nbsp;useful set of testable classes which one of them is the TestableRootWorkItem.&lt;/p&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=241738" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Community/default.aspx">Community</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category></item><item><title>Work Spaces and Smart Part Info Provider</title><link>http://msmvps.com/blogs/paulomorgado/archive/2006/10/29/Work-Spaces-and-Smart-Part-Info-Provider.aspx</link><pubDate>Sun, 29 Oct 2006 21:57:33 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:225297</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=225297</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=225297</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2006/10/29/Work-Spaces-and-Smart-Part-Info-Provider.aspx#comments</comments><description>&lt;p&gt;As I understand it, the MVP (Model/View/Presenter) design pattern states that all presentation decisions are the Presenter's responsibility.&lt;/p&gt; &lt;p&gt;In the &lt;a title="Composite UI Application Block" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp" target="_blank"&gt;CAB&lt;/a&gt; world, this should include the Smart Part Info.&lt;/p&gt; &lt;p&gt;But the IWorkspace interface only allows you to provide the Smart Part Info (a class that implements the ISmartPartInfo interface and each work space uses a specific one), or the the smart part (the View in the MVP design pattern) should know what information to provide to the work space it lives in by implementing the ISmartPartInfoProvider interface.&lt;/p&gt; &lt;p&gt;To enable the presenter to provide the smart part info changes need to be made to the IWorkspace interface and its implementations. New Show and ApplySmartPartInfo methods need to be added:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// Applies the smartPartInfo to the smartPart.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ApplySmartPartInfo(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; smartPart, ISmartPartInfoProvider smartPartInfoProvider);&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// Shows SmartPart using the given SmartPartInfo&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;param name="smartPart"&amp;gt;Smart part to show.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;param name="smartPartInfoProvider"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Show(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; smartPart, ISmartPartInfoProvider smartPartInfoProvider);&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;And it should be implemented in all the classes that implement IWorkspace:&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// Applies the smartPartInfo to the smartPart.&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ApplySmartPartInfo(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; smartPart, ISmartPartInfoProvider smartPartInfoProvider)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Practices.CompositeUI.Utility.Guard.ArgumentNotNull(smartPart, "&lt;span style="color:#8b0000;"&gt;smartPart&lt;/span&gt;");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Practices.CompositeUI.Utility.Guard.ArgumentNotNull(smartPartInfoProvider, "&lt;span style="color:#8b0000;"&gt;smartPartInfoProvider&lt;/span&gt;");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThrowIfUnsupportedSP(smartPart);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThrowIfSmartPartNotShownPreviously((TSmartPart)smartPart);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TSmartPart typedSmartPart = (TSmartPart)smartPart;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TSmartPartInfo typedSmartPartInfo = GetSupportedSPI(smartPartInfoProvider.GetSmartPartInfo(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TSmartPartInfo)));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Practices.CompositeUI.Utility.Guard.ArgumentNotNull(typedSmartPartInfo, "&lt;span style="color:#8b0000;"&gt;typedSmartPartInfo&lt;/span&gt;");&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OnApplySmartPartInfo(typedSmartPart, typedSmartPartInfo);&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// Shows SmartPart using the given SmartPartInfo&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;param name="smartPart"&amp;gt;Smart part to show.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#808080;"&gt;/// &amp;lt;param name="smartPartInfoProvider"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Show(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; smartPart, ISmartPartInfoProvider smartPartInfoProvider)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Practices.CompositeUI.Utility.Guard.ArgumentNotNull(smartPart, "&lt;span style="color:#8b0000;"&gt;smartPart&lt;/span&gt;");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Practices.CompositeUI.Utility.Guard.ArgumentNotNull(smartPartInfoProvider, "&lt;span style="color:#8b0000;"&gt;smartPartInfoProvider&lt;/span&gt;");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThrowIfUnsupportedSP(smartPart);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TSmartPart typedSmartPart = (TSmartPart)smartPart;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (smartParts.Contains(typedSmartPart))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ApplySmartPartInfo(typedSmartPart, smartPartInfoProvider);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Activate(typedSmartPart);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TSmartPartInfo typedSmartPartInfo = GetSupportedSPI(smartPartInfoProvider.GetSmartPartInfo(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TSmartPartInfo)));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Practices.CompositeUI.Utility.Guard.ArgumentNotNull(typedSmartPartInfo, "&lt;span style="color:#8b0000;"&gt;typedSmartPartInfo&lt;/span&gt;");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; smartParts.Add(typedSmartPart);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OnShow(typedSmartPart, typedSmartPartInfo);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/p&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=225297" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Community/default.aspx">Community</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category></item><item><title>Enhancing CAB's ManagedObjectCollection</title><link>http://msmvps.com/blogs/paulomorgado/archive/2006/10/22/Enhancing-CAB_2700_s-ManagedObjectCollection.aspx</link><pubDate>Sun, 22 Oct 2006 21:45:52 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:198707</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=198707</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=198707</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2006/10/22/Enhancing-CAB_2700_s-ManagedObjectCollection.aspx#comments</comments><description>&lt;p&gt;For those who don't know,&amp;nbsp;the &lt;strong&gt;ManagedObjectCollection&lt;/strong&gt; registers its&amp;nbsp;elements using the objects running type as part of the key.&lt;/p&gt; &lt;p&gt;Recently, I had the need to add and retrieve a component to the &lt;strong&gt;WorkItem&lt;/strong&gt;'s &lt;strong&gt;Items&lt;/strong&gt; collection independently of its running. I only wanted to retrieve the component (using a &lt;strong&gt;ComponentDependency&lt;/strong&gt;) with a specified name. Needless to say that I couldn't, because I was trying to retrieve an&amp;nbsp;&lt;strong&gt;object&lt;/strong&gt;,&amp;nbsp;and that was not the&amp;nbsp;running type of&amp;nbsp;the object added to the&amp;nbsp;&lt;strong&gt;WorkItem&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;I started thinking of the ability of the&amp;nbsp;&lt;strong&gt;ServiceCollection&lt;/strong&gt; to add items registering them with a different type would be very helpfully to the &lt;strong&gt;ManagedObjectCollection&lt;/strong&gt;. So, decided to add some changes.&lt;/p&gt; &lt;p&gt;To be able to build elements and register them with a different type, I had to change the Build method:&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; TItem Build(Type typeToBuild, Type typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; idToBuild, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; item)
{
	&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (idToBuild != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Contains(idToBuild, SearchMode.Local, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;))
		&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException(String.Format(CultureInfo.CurrentCulture,
			Properties.Resources.DuplicateID, idToBuild));

	&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (item != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Object.ReferenceEquals(item,
		locator.Get(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DependencyResolutionLocatorKey(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(WorkItem), &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;))))
		&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException(Properties.Resources.CannotAddWorkItemToItself, "&lt;span style="color:#8b0000;"&gt;item&lt;/span&gt;");

	&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (item == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
		item = BuildFirstTimeItem(typeToBuild, typeToRegisterAs, idToBuild, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
	&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!container.Contains(item))
		item = BuildFirstTimeItem(typeToBuild, typeToRegisterAs, idToBuild, item);
	&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;
		BuildRepeatedItem(typeToBuild, typeToRegisterAs, idToBuild, item);

	&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (TItem)item;
}

&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; BuildFirstTimeItem(Type typeToBuild, Type typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; idToBuild, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; item)
{
    item = builder.BuildUp(locator, typeToBuild, NormalizeID(idToBuild), item);

    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (typeToRegisterAs != typeToBuild)
    {
        locator.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DependencyResolutionLocatorKey(typeToRegisterAs, idToBuild), item);
        locator.Remove(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DependencyResolutionLocatorKey(typeToBuild, idToBuild));
    }

    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; item;
}

&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; BuildRepeatedItem(Type typeToBuild, Type typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; idToBuild, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; item)
{
    locator.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DependencyResolutionLocatorKey(typeToRegisterAs, NormalizeID(idToBuild)), item);
}&lt;/pre&gt;
&lt;p&gt;And, to assure compability with the existing methods:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; TItem Build(Type typeToBuild, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; idToBuild, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; item)
{
    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Build(typeToBuild, typeToBuild, idToBuild, item);
}&lt;/pre&gt;
&lt;p&gt;Now, all I needed was to add the new methods to add elements:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Add(Type typeToRegisterAs, TItem item)
{
    Add(typeToRegisterAs, item, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
}

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Add(Type typeToRegisterAs, TItem item, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; id)
{
    Guard.ArgumentNotNull(item, "&lt;span style="color:#8b0000;"&gt;item&lt;/span&gt;");
    Guard.TypeIsAssignableFromType(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TItem), typeToRegisterAs, "&lt;span style="color:#8b0000;"&gt;typeToBuild&lt;/span&gt;");

    Build(typeToRegisterAs, item.GetType(), id, item);
}

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Add&amp;lt;TTypeToRegisterAs&amp;gt;(TTypeToRegisterAs item)
    where TTypeToRegisterAs : TItem
{
    Add&amp;lt;TTypeToRegisterAs&amp;gt;(item, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
}

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Add&amp;lt;TTypeToRegisterAs&amp;gt;(TTypeToRegisterAs item, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; id)
    where TTypeToRegisterAs : TItem
{
    Guard.ArgumentNotNull(item, "&lt;span style="color:#8b0000;"&gt;item&lt;/span&gt;");

    Build(item.GetType(), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TTypeToRegisterAs), id, item);
}

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TItem AddNew(Type typeToBuild, Type typeToRegisterAs)
{
    Guard.TypeIsAssignableFromType(typeToBuild, typeToRegisterAs, "&lt;span style="color:#8b0000;"&gt;typeToBuild&lt;/span&gt;");

    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; AddNew(typeToBuild, typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
}

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TItem AddNew(Type typeToBuild, Type typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; id)
{
    Guard.TypeIsAssignableFromType(typeToBuild, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TItem), "&lt;span style="color:#8b0000;"&gt;typeToBuild&lt;/span&gt;");
    Guard.TypeIsAssignableFromType(typeToBuild, typeToRegisterAs, "&lt;span style="color:#8b0000;"&gt;typeToRegisterAs&lt;/span&gt;");

    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Build(typeToBuild, typeToRegisterAs, id, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
}

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TTypeToBuild AddNew&amp;lt;TTypeToBuild, TTypeToRegisterAs&amp;gt;()
    where TTypeToRegisterAs : TItem
    where TTypeToBuild : TTypeToRegisterAs
{
    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (TTypeToBuild)Build(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TTypeToBuild), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TTypeToRegisterAs), &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
}

&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TTypeToBuild AddNew&amp;lt;TTypeToBuild, TTypeToRegisterAs&amp;gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; id)
    where TTypeToRegisterAs : TItem
    where TTypeToBuild : TTypeToRegisterAs
{
    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (TTypeToBuild)Build(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TTypeToBuild), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TTypeToRegisterAs), id, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
}
&lt;/pre&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=198707" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Community/default.aspx">Community</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category></item><item><title>Using Remoting with CAB</title><link>http://msmvps.com/blogs/paulomorgado/archive/2006/10/11/Using-Remoting-with-CAB.aspx</link><pubDate>Tue, 10 Oct 2006 23:37:52 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:169696</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/rsscomments.aspx?PostID=169696</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/paulomorgado/commentapi.aspx?PostID=169696</wfw:comment><comments>http://msmvps.com/blogs/paulomorgado/archive/2006/10/11/Using-Remoting-with-CAB.aspx#comments</comments><description>&lt;p&gt;Anyone who has ttried to add a service implemented through &lt;a title=".NET Framework Remoting Overview" href="http://msdn2.microsoft.com/en-us/library/kwdt6w2k.aspx" target="_blank"&gt;Remoting&lt;/a&gt;&amp;nbsp;to the &lt;strong&gt;WorkItem&lt;/strong&gt;'s services collection was sadly surprised that it can't be done.&lt;/p&gt; &lt;p&gt;But why?&lt;/p&gt; &lt;p&gt;When we use the following code:&lt;/p&gt; &lt;p&gt;WorkItem.Services.Add&amp;lt;IServiceContract&amp;gt;(serviceInstance);&lt;/p&gt; &lt;p&gt;It comes to something like this:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IServiceContract).IsAssignableFrom(serviceInstance.GetType())
	&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException();&lt;/pre&gt;
&lt;p&gt;And how do we solve this problem?&lt;/p&gt;
&lt;p&gt;easy: &lt;a title="Generics in the .NET Framework" href="http://msdn2.microsoft.com/en-us/library/ms172192.aspx"&gt;generics&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All we need to do is make some changes to the&amp;nbsp;&lt;strong&gt;ServiceCollection&lt;/strong&gt; class.&lt;/p&gt;
&lt;p&gt;We change the&amp;nbsp;&lt;strong&gt;Add&amp;lt;TService&amp;gt;(TService serviceInstance)&lt;/strong&gt; method to look like this:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Add&amp;lt;TService&amp;gt;(TService serviceInstance) 
{ 
	Guard.ArgumentNotNull(serviceInstance, "&lt;span style="color:#8b0000;"&gt;serviceInstance&lt;/span&gt;"); 

	Build&amp;lt;TService&amp;gt;(serviceInstance); 
} 
&lt;/pre&gt;
&lt;p&gt;At this point we need to refactor the&amp;nbsp;&lt;strong&gt;Build(Type typeToBuild, Type typeToRegisterAs, object serviceInstance)&lt;/strong&gt; method to have two entry points to the common its&amp;nbsp;logic:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Build(Type typeToBuild, Type typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; serviceInstance) 
{ 
	Guard.TypeIsAssignableFromType(typeToBuild, typeToRegisterAs, "&lt;span style="color:#8b0000;"&gt;typeToBuild&lt;/span&gt;"); 

	&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; BuildImplementation(typeToBuild, typeToRegisterAs, serviceInstance); 
} 

&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; TService Build&amp;lt;TService&amp;gt;(&lt;span style="color:#0000ff;"&gt;TService&lt;/span&gt; serviceInstance) 
{ 
	&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (TService)BuildImplementation(serviceInstance.GetType(), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TService), serviceInstance); 
} 

&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; BuildImplementation(Type typeToBuild, Type typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; serviceInstance) 
{ 
	&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (locator.Contains(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DependencyResolutionLocatorKey(typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;), SearchMode.Local)) 
		&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(CultureInfo.CurrentCulture,&lt;br&gt;			Properties.Resources.DuplicateService, typeToRegisterAs.FullName)); 

	&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (serviceInstance == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;) 
		serviceInstance = BuildFirstTimeItem(typeToBuild, typeToRegisterAs, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;); 
	&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!container.Contains(serviceInstance)) 
		serviceInstance = BuildFirstTimeItem(typeToBuild, typeToRegisterAs, serviceInstance); 
	&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; 
		BuildRepeatedItem(typeToRegisterAs, serviceInstance); 

	&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; serviceInstance; 
} 
&lt;/pre&gt;
&lt;p&gt;Easy, isn't it?&amp;nbsp;And I suspect that that's not the only improvement like this that we can get into&amp;nbsp;&lt;a title="Composite UI Application Block" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp" target="_blank"&gt;CAB&lt;/a&gt;. 
&lt;p&gt;Oh!&amp;nbsp;And why would we&amp;nbsp;wanto to use&amp;nbsp;&lt;a title=".NET Framework Remoting Overview" href="http://msdn2.microsoft.com/en-us/library/kwdt6w2k.aspx" target="_blank"&gt;Remoting&lt;/a&gt;?&amp;nbsp;To use&amp;nbsp;&lt;a href="http://nmock.org/"&gt;NMock2&lt;/a&gt; in the unit tests, of course!&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;strong&gt;Updated: November 14th, 2006&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;Changed:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; TService Build&amp;lt;TService&amp;gt;(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; serviceInstance)
{
	Guard.TypeIsCompatibleType&amp;lt;TService&amp;gt;(serviceInstance, "&lt;span style="color:#8b0000;"&gt;typeToBuild&lt;/span&gt;");&lt;br&gt;
	&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (TService)BuildImplementation(serviceInstance.GetType(), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TService), serviceInstance);
}
&lt;/pre&gt;
&lt;p&gt;Removed:&lt;/p&gt;
&lt;p&gt;And add the&amp;nbsp;&lt;strong&gt;TypeIsCompatibleType&amp;lt;T&amp;gt;(object providedInstance, string argumentName)&lt;/strong&gt; method to the &lt;strong&gt;Guard&lt;/strong&gt; class:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; TypeIsCompatibleType&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; providedInstance, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; argumentName) 
{ 
	&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!(providedInstance &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; T)) 
		&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(CultureInfo.CurrentCulture,&lt;br&gt;			Properties.Resources.TypeNotCompatible, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(T), providedInstance.GetType()),&lt;br&gt;			argumentName); 
} &lt;/pre&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=169696" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MSDN/default.aspx">MSDN</category></item><item><title>Fighting with CAB visualizers and visualizations</title><link>http://msmvps.com/blogs/paulomorgado/archive/2006/10/10/Fighting-with-CAB-visualizers-and-visualizations.aspx</link><pubDate>Tue, 10 Oct 2006 22:44:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:169530</guid><dc:creator>Paulo Morgado</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Anyone who has previously developed with &lt;a title="Composite UI Application Block" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp" target="_blank"&gt;CAB&lt;/a&gt; knows that documentation and information are scarce, but when one faces something like I recently faced, everything becomes even more difficult.&lt;/p&gt;
&lt;p&gt;When I tried to use a &lt;em&gt;visualizer&lt;/em&gt; with my application, I was faced with something very strange (to say the least).&lt;/p&gt;
&lt;p&gt;(For those who don&amp;#39;t know it, a &lt;em&gt;visualizer&lt;/em&gt; is a &lt;a title="Composite UI Application Block" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/cab.asp" target="_blank"&gt;CAB&lt;/a&gt; component that collects information about the &lt;em&gt;WorkItems&lt;/em&gt; in the application and makes that information available to &lt;em&gt;visualizations&lt;/em&gt; that will display it.)&lt;/p&gt;
&lt;p&gt;Finding out that I needed a &lt;em&gt;visualizer&lt;/em&gt; element in my configuration file it wasn&amp;#39;t easy. But nothing prepared me to the fact that this element is just a collection of &lt;em&gt;visualizations&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The configuration section looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR:#0000ff;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;visualizer&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;add&lt;/span&gt; &lt;span style="COLOR:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="COLOR:#0000ff;"&gt;&amp;quot;&lt;em&gt;visualization type&lt;/em&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
	...
	&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;add&lt;/span&gt; &lt;span style="COLOR:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="COLOR:#0000ff;"&gt;&amp;quot;&lt;em&gt;visualization type&lt;/em&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;visualizer&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Would it be more logical to have something like this?&lt;/p&gt;&lt;pre&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;visualizer&lt;/span&gt; &lt;span style="COLOR:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="COLOR:#0000ff;"&gt;&amp;quot;&lt;em&gt;visualizer type&lt;/em&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;visualizations&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;add&lt;/span&gt; &lt;span style="COLOR:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="COLOR:#0000ff;"&gt;&amp;quot;&lt;em&gt;visualization type&lt;/em&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
		...
		&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;add&lt;/span&gt; &lt;span style="COLOR:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="COLOR:#0000ff;"&gt;&amp;quot;&lt;em&gt;visualization type&lt;/em&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
	&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;visualizations&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#800000;"&gt;visualizer&lt;/span&gt;&lt;span style="COLOR:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;We could even configure the type of the visualizer, which we can&amp;#39;t with the current architecture.&lt;/p&gt;
&lt;p&gt;And this pearl came out of &lt;a title="Patterns &amp;amp; Practices Group" href="http://msdn.microsoft.com/practices/"&gt;PAG&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=169530" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SCSF/default.aspx">SCSF</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/SoftDev/default.aspx">SoftDev</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/paulomorgado/archive/tags/MVP/default.aspx">MVP</category></item></channel></rss>