<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Malisa Ncube - C# and .NET Delights</title>
        <link>http://geekswithblogs.net/malisancube/Default.aspx</link>
        <description>Mumblings about the software development using Microsoft technologies.</description>
        <language>en-US</language>
        <copyright>Malisa L. Ncube</copyright>
        <managingEditor>malisa.ncube@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <image>
            <title>Malisa Ncube - C# and .NET Delights</title>
            <url>http://geekswithblogs.net/images/RSS2Image.gif</url>
            <link>http://geekswithblogs.net/malisancube/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Uganda .NET Usergroup meeting</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/10/22/uganda-.net-usergroup-meeting.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;We have scheduled for a &lt;strong&gt;.NET Usergroup&lt;/strong&gt; meeting next week on the 30th October 2009. I arranged with our training department and they have agreed to ensure that we have the room, support in resources including a laptop, projector and anything else which may be necessary. Happy days! They have also guaranteed that we can have the room each month on the last Friday. I had been in communication with &lt;/font&gt;&lt;a href="http://www.craigmurphy.com" target="_blank"&gt;&lt;font size="2"&gt;Craig Murphy&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;, who took up my tweet and made it his task to see how we can get helped in making this possible while aligning to Microsoft principles.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;I’m very excited about this opportunity and believe that we will take it up as developers in Uganda and share, learn, educate, socialise and make value out of our usergroup and engagement in the development of software using Microsoft technologies.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;It will also be nice to have a number of activities e.g. &lt;/font&gt;&lt;a href="http://www.nerddinner.com/" target="_blank"&gt;&lt;font size="2"&gt;NerdDinner&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; and GeekBeer or something like that.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;If you are wondering how to get to our training centre, just get to Mulago and enter the hospital complex through the main gate and just proceed straight ahead and you will see the building below.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt; &lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Uganda.NETUsergroupmeeting_EEF5/clip_image002_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Uganda.NETUsergroupmeeting_EEF5/clip_image002_thumb.gif" width="362" height="272" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Our Training room is shown below.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt; &lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Uganda.NETUsergroupmeeting_EEF5/clip_image002%5B5%5D.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002[5]" border="0" alt="clip_image002[5]" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Uganda.NETUsergroupmeeting_EEF5/clip_image002%5B5%5D_thumb.gif" width="385" height="242" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;NOTE: If you are going to attend i will need to know so that we can reserve space and help you get here, so drop an email to me at malisa [dot] ncube [et] gmail [dot] com.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;_______________________________________________________________________________________________&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;font size="2"&gt;&lt;strong&gt;Uganda .NET User Group Meeting&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;&lt;font size="2"&gt;Venue: Infectious Diseases Institute (Training Centre)&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;font size="2"&gt;&lt;strong&gt;Date: 30th October 2009&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;font size="2"&gt;&lt;strong&gt;Time: 6:00 PM to 8:00 PM (Prompt)&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;font size="2"&gt;&lt;strong&gt;Speaker: Malisa Ncube &lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;font size="2"&gt;&lt;strong&gt;Topic: How we are to run the Usergroup (Discussion)&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="center"&gt; &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:157d5750-bf53-4cea-9def-9a60c52354f5" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/.NET+Usergroup" rel="tag"&gt;.NET Usergroup&lt;/a&gt;,&lt;a href="http://technorati.com/tags/.NET" rel="tag"&gt;.NET&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135652"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135652" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/135652.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/10/22/uganda-.net-usergroup-meeting.aspx</guid>
            <pubDate>Thu, 22 Oct 2009 14:40:49 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/135652.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/10/22/uganda-.net-usergroup-meeting.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/135652.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/135652.aspx</trackback:ping>
        </item>
        <item>
            <title>Something to smile about after the project implementation</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/07/06/something-to-smile-about-after-the-project-implementation.aspx</link>
            <description>&lt;p&gt;Some of the feedback from the users. ICEA stands for &lt;strong&gt;I&lt;/strong&gt;ntegrated &lt;strong&gt;C&lt;/strong&gt;linic &lt;strong&gt;E&lt;/strong&gt;nterprise &lt;strong&gt;A&lt;/strong&gt;pplication, the EMR system which we have just implemented.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Somethingtosmileaboutaftertheprojectimpl_A61E/image5.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Somethingtosmileaboutaftertheprojectimpl_A61E/image5_thumb.png" width="439" height="330" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I thank the users for being patient with us during requirements gathering, and for not laughing at some of our stupid questions.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:52669392-a47f-48b4-b7d8-0791aa3e142c" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/EMR" rel="tag"&gt;EMR&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133306"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133306" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/133306.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/07/06/something-to-smile-about-after-the-project-implementation.aspx</guid>
            <pubDate>Tue, 07 Jul 2009 06:24:08 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/133306.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/07/06/something-to-smile-about-after-the-project-implementation.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/133306.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/133306.aspx</trackback:ping>
        </item>
        <item>
            <title>The so called EMR software (Integrated Clinic Enterprise Application &amp;ndash; ICEA.NET)</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/06/12/the-so-called-emr-software-integrated-clinic-enterprise-application-ndash.aspx</link>
            <description>&lt;p&gt;This post is just to show some of the screenshots of the EMR software that we developed and deployed in the past few weeks in our clinic. Some of the features include:&lt;/p&gt;  &lt;p&gt;- Patient Registration&lt;/p&gt;  &lt;p&gt;- Return visit entry and scheduling&lt;/p&gt;  &lt;p&gt;- Entry for Patient history, Vital signs, ART History, Online Prescriptions, Online lab orders, Counseling, Workflow&lt;/p&gt;  &lt;p&gt;- Role base security with windows based authentication&lt;/p&gt;  &lt;p&gt;- Office 2007 Themes (Don’t know whether to call this a feature) Thanks to &lt;a href="http://www.componentfactory.com/" target="_blank"&gt;Component Factory&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ThesocalledEMRsoftwareIntegratedClin.NET_103F9/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ThesocalledEMRsoftwareIntegratedClin.NET_103F9/image_thumb.png" width="772" height="222" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;The lab requisitions view&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ThesocalledEMRsoftwareIntegratedClin.NET_103F9/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ThesocalledEMRsoftwareIntegratedClin.NET_103F9/image_thumb_1.png" width="548" height="403" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Some technical summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;- Based on a custom plugin framework &lt;/p&gt;  &lt;p&gt;- SQL Server 2005 (can be configured for any database)&lt;/p&gt;  &lt;p&gt;- Uses Krypton Components from &lt;a href="http://www.componentfactory.com/" target="_blank"&gt;Component Factory&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;- Uses &lt;a href="http://www.fast-report.com/" target="_blank"&gt;Fastreport.NET&lt;/a&gt; from &lt;/p&gt;  &lt;p&gt;- .NET Framework 3.5 and Visual Studio 2008&lt;/p&gt;  &lt;p&gt;- C#&lt;/p&gt;  &lt;p&gt;- Nant for unit testing&lt;/p&gt;  &lt;p&gt;- Cruise Control  &amp;amp; Subversion for Continuous Integration&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Other&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;- Currently about 30 users online and using the system, simultaneously, they will increase to 60 before the end of the month as we include more users.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Things to do in the soon future &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;- Axum – there is need to fully utilise the processor power, therefore a parallel approach will increase efficiency of out applications.&lt;/p&gt;  &lt;p&gt;- Biometrics – verification of U are U.&lt;/p&gt;  &lt;p&gt;- SQL Server Business Intelligence suite – for analytical purposes&lt;/p&gt;  &lt;p&gt;-  SQL Server reporting services / Some custom reporting portal&lt;/p&gt;  &lt;p&gt;- Touch screen computers for vital signs / embedded software supporting devices for vital signs&lt;/p&gt;  &lt;p&gt;- Add plugins for research modules&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0e2b355b-d02a-425d-bc95-4432a2faa2fd" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/EMR" rel="tag"&gt;EMR&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Electronic+Medical+Records" rel="tag"&gt;Electronic Medical Records&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Clinic+software" rel="tag"&gt;Clinic software&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132773"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132773" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/132773.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/06/12/the-so-called-emr-software-integrated-clinic-enterprise-application-ndash.aspx</guid>
            <pubDate>Fri, 12 Jun 2009 15:31:42 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/132773.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/06/12/the-so-called-emr-software-integrated-clinic-enterprise-application-ndash.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/132773.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/132773.aspx</trackback:ping>
        </item>
        <item>
            <title>Managed Extensibility Framework 101 (b)</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/06/09/managed-extensibility-framework-101-b.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ManagedExtensibilityFramework101b_8CF6/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ManagedExtensibilityFramework101b_8CF6/clip_image002_thumb.jpg" width="223" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;1. Introduction&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;This posting is a continuation from the previous post on Managed Extensibility Framework (MEF). If you are a new to MEF you will need to visit the MEF blog at &lt;a href="http://mef.codeplex.com/" target="_blank"&gt;Codeplex&lt;/a&gt; or Glenn’s Blog &lt;a href="http://codebetter.com/blogs/glenn.block/" target="_blank"&gt;here&lt;/a&gt;. You will need to download the &lt;a href="http://mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=25797" target="_blank"&gt;framework&lt;/a&gt; so you can also find out how it leverages the power of extensibility into your applications.&lt;/p&gt;  &lt;p&gt;In the previous post I showed how you can quickly create a MEF application and use the attributes to &lt;i&gt;import&lt;/i&gt; and &lt;i&gt;export&lt;/i&gt; different parts, and use the container to compose the parts. My example used parts from the same assembly - using &lt;i&gt;Assembly.GetExecutingAssembly();&lt;/i&gt; but in this example I will include separately compiled assemblies (plugins) which are read by the &lt;b&gt;DirectoryCatalog&lt;/b&gt; from a specific location. &lt;/p&gt;  &lt;p&gt;So essentially what you will see the following in this post&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The Aggregate Catalog &lt;/li&gt;    &lt;li&gt;The Directory Catalog &lt;/li&gt;    &lt;li&gt;Making the host accessible from a plugin. &lt;/li&gt;    &lt;li&gt;A bit of Metadata attributes &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Let look at what we had to do to come up with the new example.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;2. The Aggregate Catalog&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;To do this we had to combine the &lt;b&gt;AssemblyCatalog&lt;/b&gt; and the &lt;b&gt;DirectoryCatalog&lt;/b&gt; into an &lt;b&gt;AggregateCatalog&lt;/b&gt;. The AggregateCatalog combines a number of catalogs into one, and that is exactly what we wanted to do because we wanted the exports from the external assemblies to satisfy the imports of the executing assembly.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// The main entry point for the application.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[STAThread]&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main()&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    Application.EnableVisualStyles();&lt;br /&gt;    Application.SetCompatibleTextRenderingDefault(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;    Program program = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Program();&lt;br /&gt;    var host = program.Compose();&lt;br /&gt;    &lt;br /&gt;    Application.Run(host &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Form1); &lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// This will compose the parts as defined&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;returns&amp;gt;IPluginHost&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IPluginHost Compose()&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;    var catalog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AggregateCatalog(); &lt;span style="color: #008000"&gt;//The special type of catalog that combines a number of catalogs&lt;/span&gt;&lt;br /&gt;    catalog.Catalogs.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AssemblyCatalog(Assembly.GetExecutingAssembly()));&lt;br /&gt;    catalog.Catalogs.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DirectoryCatalog(&lt;span style="color: #006080"&gt;@".\Plugins"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"*.dll"&lt;/span&gt;));&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #008000"&gt;//At this poing the catalog contains the (1) ExecutingAssembly and (2) the assenblies in \Plugin folder&lt;/span&gt;&lt;br /&gt;    CompositionContainer container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositionContainer(catalog);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; container.GetExportedObject&amp;lt;IPluginHost&amp;gt;();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;3. Contracts&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The first thing to do was to create a project which contains &lt;i&gt;contracts&lt;/i&gt;. These are simply interfaces that will be shared between the host application and the plugins. The contracts define the expected common operations, data items between plugins and host application. They make a uniform way in which you can interact with those objects, while oblivious about the implementation details. As shown below the &lt;i&gt;PluginHost&lt;/i&gt; is the contract implemented by the host application and &lt;i&gt;IPlugin&lt;/i&gt; by plugins. You will also notice that we have included the &lt;i&gt;IPluginHost&lt;/i&gt; in the &lt;i&gt;IPlugin&lt;/i&gt; interface… This is because we want each of the plugins to perform some functions on the plugin host, for example show the progress bar, change theme and so forth.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IPluginHost&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ShowProgress(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; message, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; percentage);&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ChangeTheme(Color color);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IPlugin&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;    IPluginHost Host {get;}&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Version { get; }&lt;br /&gt;    ToolStripItem[] ToolStripItems { get; } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;4. Plugins&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The next thing is to create the plugins. The code below shows that the plugin imports the IPluginHost, which in our case is the main form. We access the host / shell using &lt;i&gt;Host&lt;/i&gt;, and as shown in the example below in the button1_Click method. We can send commands to the host ‘s progress bar using Host.ShowProgress("Processing...", i).&lt;/p&gt;

&lt;p&gt;We have also decided to decorate the plugin with some &lt;i&gt;ExportMetadata&lt;/i&gt; attribute which we will access from the container. &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;[Export(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPlugin))]&lt;br /&gt;[ExportMetadata(&lt;span style="color: #006080"&gt;"Name"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"Process Starter Plugin"&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ProcessPlugin : UserControl, IPlugin&lt;br /&gt;{&lt;br /&gt;    &lt;br /&gt;    [Import(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPluginHost))]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IPluginHost host;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IPluginHost Host&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; host;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ProcessPlugin()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; IPlugin Members&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Version&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Assembly.GetExecutingAssembly().GetName().Version.ToString();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ToolStripItem[] ToolStripItems&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; button1_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;/* Some long process*/&lt;/span&gt; &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; b = 0; b &amp;lt; 10000000; b++) ;&lt;br /&gt;            Host.ShowProgress(&lt;span style="color: #006080"&gt;"Processing..."&lt;/span&gt;, i);&lt;br /&gt;        }&lt;br /&gt;        Host.ShowProgress(&lt;span style="color: #006080"&gt;""&lt;/span&gt;, 0);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;5. The Plugin Host / Shell&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;This is the main form which hosts the plugins. In it, we have declared an &lt;i&gt;ExportCollection&lt;/i&gt; of &lt;i&gt;IPlugin&lt;/i&gt; and decorated it with the [&lt;i&gt;Import&lt;/i&gt;] attribute, so that during composition we will have all the &lt;i&gt;IPlugin&lt;/i&gt; objects created and assigned to it. The advantage of using the &lt;i&gt;ExportCollection&lt;/i&gt; than the &lt;i&gt;IEnumerable&lt;/i&gt; is that it enables us to also extract the metadata from the exported part.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;[Export(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPluginHost))]&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Form1 : Form, IPluginHost&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Plugins will be imported into this property&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    [Import(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPlugin))]&lt;br /&gt;    ExportCollection&amp;lt;IPlugin&amp;gt; Plugins { get; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Form1()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Form1_Load(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;//Show plugins&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;        listBox1.Items.Clear();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var plugin &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Plugins)&lt;br /&gt;        {&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #008000"&gt;//get the Plugin&lt;/span&gt;&lt;br /&gt;            var plg = plugin.GetExportedObject();&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #008000"&gt;//Check if it has toolstrip items and add them to the main form &lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (plg.ToolStripItems != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                        toolStrip1.Items.AddRange(plg.ToolStripItems);&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #008000"&gt;//Add the visible area of the plugin to the main form&lt;/span&gt;&lt;br /&gt;            tableLayoutPanel1.Controls.Add(plg &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Control);&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #008000"&gt;//Read the metadata and show the Name Property and the Version value from the plugins&lt;/span&gt;&lt;br /&gt;            listBox1.Items.Add(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"{0} {1}"&lt;/span&gt;, plugin.Metadata[&lt;span style="color: #006080"&gt;"Name"&lt;/span&gt;].ToString(), plg.Version));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;  &lt;br /&gt;    &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; IHost Members&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Show Progress bar with text message. This is controllable from the plugins because it is part&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// of the IPluginHost interface which is known by all plugins.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name="message"&amp;gt;Message shown on status bar&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name="percentage"&amp;gt;progress indicator value&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; ShowProgress(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; message, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; percentage)&lt;br /&gt;    {&lt;br /&gt;        toolStripStatusLabel1.Text = message;&lt;br /&gt;        toolStripProgressBar1.Value = percentage;&lt;br /&gt;        Application.DoEvents();&lt;br /&gt;        toolStripStatusLabel1.Visible = percentage &amp;gt; 0;&lt;br /&gt;        toolStripProgressBar1.Visible = toolStripStatusLabel1.Visible;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// This changes the color of the background and is controllable from the Plugins.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name="color"&amp;gt;Color to be use on background&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; ChangeTheme(Color color)&lt;br /&gt;    {&lt;br /&gt;        BackColor = color;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;6. Conclusion&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;This example has attempted to illustrate how you can use the Managed Extensibility Framework to create a small plug-in application. We have also tried to make the host application and plugins independent, and have them abide to the contracts. The contracts were defined and used by the plugins to perform some actions on the plugin-host / shells regardless of the implementation details. The plugins also implemented the contracts which enabled them to have uniformity and to expose common methods and properties.&lt;/p&gt;

&lt;p&gt;When the application starts; the running assembly and the plugins are read and mappings made between imports and exports (composition). We then get the exported object called &lt;i&gt;IPluginHost&lt;/i&gt; which we know is the main form and run it.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;b&gt;7. Source Code&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Download source &lt;a href="http://cid-dac24aabcbbee919.skydrive.live.com/browse.aspx/.Public?uc=2" target="_blank"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;
  &lt;/p&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1b683c64-60ce-4cf1-a6a3-f34dd7e85737" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;,&lt;a href="http://technorati.com/tags/.NET" rel="tag"&gt;.NET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Managed+Extensible+Framework" rel="tag"&gt;Managed Extensible Framework&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Plugin+Framework" rel="tag"&gt;Plugin Framework&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132729"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132729" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/132729.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/06/09/managed-extensibility-framework-101-b.aspx</guid>
            <pubDate>Wed, 10 Jun 2009 07:16:26 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/132729.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/06/09/managed-extensibility-framework-101-b.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/132729.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/132729.aspx</trackback:ping>
        </item>
        <item>
            <title>Managed Extensibility Framework 101 - (a)</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/05/26/managed-extensibility-framework-101---a.aspx</link>
            <description>&lt;p&gt;This is the first posting on MEF, in which I will be explaining some things that I discovered while playing around with MEF. I should say that all the postings on my blog, including this subject do not represent my employer or any other organization, they are merely my mumblings based on my work that I do and whatever in find interesting and would like to share. Use it at your own risk, but it works on my machine.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ManagedExtensibilityFramework101a_F112/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/ManagedExtensibilityFramework101a_F112/clip_image002_thumb.jpg" width="244" height="221" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To start with I would like you to read about the architecture of the MEF framework from the MEF &lt;a href="http://mef.codeplex.com/Wiki/View.aspx?title=Guide" target="_blank"&gt;Codeplex site&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;In my MEF101, I present an example which shows how you can import composable parts from your assemble and let MEF compose and satisfy imports and enable you to come up with a simple interface made from different parts.&lt;/p&gt;  &lt;p&gt;I created the IPlugin interface which I use in my exports. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// IPlugin Interface&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// Used by all the composable parts which will be used as plugins&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IPlugin&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;All rectangle items visible are simple UserControls which implement the IPlugin contract. Notice that I have placed an &lt;strong&gt;[Export]&lt;/strong&gt; attribute. This informs MEF that during composition that if there is something which needs &lt;strong&gt;[Imports]&lt;/strong&gt; IPlugin, then the MEF will create it and satisfy that import.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// Plugin1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// Example Plugin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[Export(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPlugin))]&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Plugin1 : UserControl, IPlugin&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Plugin1()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;All the plugins in this example have this same structure. I just changed the background color in the designer to so that we can tell that they are different.&lt;/p&gt;

&lt;p&gt;The Main form has the following code. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// Form1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// The main form. We need to have the [Export] attribute on it because on the Program.cs&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// we compose it using MEF and get its instance as an ExportedObject.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;[Export]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Form1 : Form&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Plugins&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// These imports will be satisfied by instances of the IPlugin 's&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// which in this case is the user controls with different colors.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    [Import]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IEnumerable&amp;lt;IPlugin&amp;gt; Plugins;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Form1()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Form1_Load(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// We loop through all the instances of the plugins an add them to the tableLayoutPanel&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// and because we know that all of them are UserControls we can cast the as Control.&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var plugin &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Plugins)&lt;br /&gt;        {&lt;br /&gt;            (plugin &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Control).Dock = DockStyle.Fill;&lt;br /&gt;            tableLayoutPanel1.Controls.Add(plugin &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Control);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The Program.cs has the following code.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// The main entry point for the application.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    [STAThread]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main()&lt;br /&gt;    {&lt;br /&gt;        Application.EnableVisualStyles();&lt;br /&gt;        Application.SetCompatibleTextRenderingDefault(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        var form1 = Compose();&lt;br /&gt;        Application.Run(form1);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Form1 Compose()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;//Create a catalog - in this case we want to import the composable parts which exist in this&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;//assembly, so we will use the AssemblyCatalog against the current assembly.&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;//It is also possible to import assemblies from external assemblies using the DirectoryCatalog.&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;//Furthermore you can combine a number of catalogs into an AggregateCatalog.&lt;/span&gt;&lt;br /&gt;        var catalog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AssemblyCatalog(Assembly.GetExecutingAssembly());&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;//Create the Container - then pass the catalog into the container &lt;/span&gt;&lt;br /&gt;        var container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositionContainer(catalog);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;//Return the instance of Form1.&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; container.GetExportedObject&amp;lt;Form1&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;And that’s all. Look at how we create the instance of Form1 class and use the Application class to run it.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;You can download the source &lt;a href="http://cid-dac24aabcbbee919.skydrive.live.com/browse.aspx/.Public?uc=2" target="_blank"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:592c4d7d-1164-41a6-bb33-76749c7435f1" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Managed+Extensible+Framework" rel="tag"&gt;Managed Extensible Framework&lt;/a&gt;,&lt;a href="http://technorati.com/tags/.NET" rel="tag"&gt;.NET&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132426"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132426" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/132426.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/05/26/managed-extensibility-framework-101---a.aspx</guid>
            <pubDate>Wed, 27 May 2009 05:13:42 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/132426.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/05/26/managed-extensibility-framework-101---a.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/132426.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/132426.aspx</trackback:ping>
        </item>
        <item>
            <title>Catching unhandled exceptions and sending them to BugTracker.NET</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/05/26/catching-unhandled-exceptions-and-sending-them-to-bugtracker.net.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Catchingunhandledexceptionsandsendin.NET_AA5F/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Catchingunhandledexceptionsandsendin.NET_AA5F/clip_image002_thumb.jpg" width="616" height="396" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;1. Introduction&lt;/h3&gt;  &lt;p&gt;Have you ever been in a situation where the users are unable to explain how an error was displayed on their computer and moreover describe the details of the error message? Well… I wonder why I asked when I already knew the answer you’ll say.&lt;/p&gt;  &lt;p&gt;A few weeks ago, the some users started testing the system; I realized our method of tracking bugs was not nearly good. We had an excel spreadsheet which had bug details and how we can reproduce the bug. We had problems with that each tester was now using their own version of a bug tracking spreadsheet, since excel does not allow shared access, so I downloaded the opensource &lt;a href="http://ifdefined.com/bugtrackernet.html"&gt;Bugtracker.NET&lt;/a&gt; from codeplex to see if it could be of help, since we do not have  the Team Foundation Server. &lt;/p&gt;  &lt;h3&gt;2. Trapping unhandled exceptions&lt;/h3&gt;  &lt;p&gt;The first thing to do is to catch all unhandled exceptions, and to do that you added an event handler in the Application.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;Program.cs&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Program&lt;br /&gt;{     &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main()         &lt;br /&gt;    {             &lt;br /&gt;        Application.EnableVisualStyles();             &lt;br /&gt;        Application.SetCompatibleTextRenderingDefault(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);             &lt;br /&gt;        ....             &lt;br /&gt;        ....                 &lt;br /&gt;        Application.ApplicationExit += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(Application_ApplicationExit);&lt;br /&gt;        ....             &lt;br /&gt;        ....         &lt;br /&gt;    }          &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Application_ThreadException(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.Threading.ThreadExceptionEventArgs e)&lt;br /&gt;{&lt;br /&gt;    Bug bug = Bug.Create();&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; screenshotFile = bug.CaptureScreenShot();&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; sendScreenShot = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; bugSent = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;    TaskDialog exceptionDialog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TaskDialog();&lt;br /&gt;    exceptionDialog.MainIcon = TaskDialogIcon.Error;&lt;br /&gt;    exceptionDialog.MainInstruction = e.Exception.Message;&lt;br /&gt;    exceptionDialog.UseCommandLinks = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;    exceptionDialog.WindowTitle = &lt;span style="color: #006080"&gt;"Error Occured!"&lt;/span&gt;;&lt;br /&gt;    exceptionDialog.Content = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"Unhandled Exception: {0}\nSource: {1}\nObject: {2}"&lt;/span&gt;, e.Exception.Message, e.Exception.Source, e.Exception.TargetSite.ToString());&lt;br /&gt;    exceptionDialog.ExpandedByDefault = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;    exceptionDialog.ExpandedInformation = e.Exception.StackTrace;&lt;br /&gt;&lt;br /&gt;    exceptionDialog.VerificationText = &lt;span style="color: #006080"&gt;"Do you want to send screenshot?"&lt;/span&gt;;&lt;br /&gt;    exceptionDialog.VerificationFlagChecked = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;    exceptionDialog.FooterIcon = TaskDialogIcon.Information;&lt;br /&gt;&lt;br /&gt;    TaskDialogButton sendButton = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TaskDialogButton();&lt;br /&gt;    sendButton.ButtonId = 101;&lt;br /&gt;    sendButton.ButtonText = &lt;span style="color: #006080"&gt;"Send"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    TaskDialogButton cancelButton = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TaskDialogButton();&lt;br /&gt;    cancelButton.ButtonId = 102;&lt;br /&gt;    cancelButton.ButtonText = &lt;span style="color: #006080"&gt;"Don't Send"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    exceptionDialog.Buttons = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TaskDialogButton[] { sendButton, cancelButton };&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = exceptionDialog.Show(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; sendScreenShot);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (result == sendButton.ButtonId)&lt;br /&gt;    {&lt;br /&gt;        bug.BugUrl = &lt;span style="color: #006080"&gt;"http://server:88/insert_bug.aspx"&lt;/span&gt;;&lt;br /&gt;        bug.MailText = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"Unhandled Exception: {0}\nSource: {1}\nObject: {2}\nTrace: {3}"&lt;/span&gt;, &lt;br /&gt;            e.Exception.Message, e.Exception.Source, e.Exception.TargetSite.ToString(), e.Exception.StackTrace);&lt;br /&gt;        bug.ProjectId = &lt;span style="color: #006080"&gt;"ICEA.NET"&lt;/span&gt;;&lt;br /&gt;        bug.UserName = &lt;span style="color: #006080"&gt;"tester"&lt;/span&gt;;&lt;br /&gt;        bug.Password = &lt;span style="color: #006080"&gt;"tester"&lt;/span&gt;;&lt;br /&gt;        bug.Subject = &lt;span style="color: #006080"&gt;"User: ["&lt;/span&gt; + WindowsIdentity.GetCurrent().Name + &lt;span style="color: #006080"&gt;"] "&lt;/span&gt;+ e.Exception.Message;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (sendScreenShot)&lt;br /&gt;            bugSent = bug.WithAttachment(screenshotFile)&lt;br /&gt;                         .ComposeMail()&lt;br /&gt;                         .SendBugReport();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            bugSent = bug.ComposeMail()&lt;br /&gt;                         .SendBugReport();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (bugSent)&lt;br /&gt;            MessageBox.Show(&lt;span style="color: #006080"&gt;"Details of error have sent to development team! Thanks."&lt;/span&gt;, &lt;span style="color: #006080"&gt;"Message Sent"&lt;/span&gt;, MessageBoxButtons.OK, MessageBoxIcon.Information);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            MessageBox.Show(&lt;span style="color: #006080"&gt;"Could not send error details to development team!"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"Message Failure"&lt;/span&gt;, MessageBoxButtons.OK, MessageBoxIcon.Error);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The above code snippet will ensure that if an exception is unhandled then the method Application_ThreadException will be executed and the exception details are passed as an argument.&lt;/p&gt;

&lt;h3&gt;3. Capturing the screenshot&lt;/h3&gt;

&lt;p&gt;This is a very important part, because the screenshot will be attached to the email which is then sent to the server, so we can know what the user was doing when the exception occurred. The image is then converted to base64 format. This is simply changing the image to text so we can send it over HTTP.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ImageToBase64(Image image,  System.Drawing.Imaging.ImageFormat format)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (MemoryStream ms = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MemoryStream())&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Convert Image to byte[]&lt;/span&gt;&lt;br /&gt;                image.Save(ms, format);&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] imageBytes = ms.ToArray();&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Convert byte[] to Base64 String&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; base64String = Convert.ToBase64String(imageBytes);&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; base64String;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; CaptureImage(Point SourcePoint, Point DestinationPoint, Rectangle SelectionRectangle)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (Bitmap bitmap = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Bitmap(SelectionRectangle.Width, SelectionRectangle.Height))&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (Graphics g = Graphics.FromImage(bitmap))&lt;br /&gt;                {&lt;br /&gt;                    g.CopyFromScreen(SourcePoint, DestinationPoint, SelectionRectangle.Size);&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color: #008000"&gt;//return the string which represent the image&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ImageToBase64(bitmap, ImageFormat.Jpeg);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; CaptureScreenShot()&lt;br /&gt;        {&lt;br /&gt;            Rectangle bounds = Screen.GetBounds(Screen.GetBounds(Point.Empty));&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; CaptureImage(Point.Empty, Point.Empty, bounds);&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;h3&gt;4. Composing the Bug Mail&lt;/h3&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Bug ComposeMail()&lt;br /&gt;{&lt;br /&gt;    mail = &lt;span style="color: #006080"&gt;"&amp;amp;username="&lt;/span&gt; + HttpUtility.UrlEncode(_UserName) +&lt;br /&gt;           &lt;span style="color: #006080"&gt;"&amp;amp;password="&lt;/span&gt; + HttpUtility.UrlEncode(_Password) +&lt;br /&gt;           &lt;span style="color: #006080"&gt;"&amp;amp;from="&lt;/span&gt; + HttpUtility.UrlEncode(_UserName) +&lt;br /&gt;           &lt;span style="color: #006080"&gt;"&amp;amp;short_desc="&lt;/span&gt; + HttpUtility.UrlEncode(_Subject) +&lt;br /&gt;           &lt;span style="color: #006080"&gt;"&amp;amp;projectid="&lt;/span&gt; + HttpUtility.UrlEncode(_ProjectId);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_Attachment != &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty)&lt;br /&gt;        mail += &lt;span style="color: #006080"&gt;"&amp;amp;message="&lt;/span&gt; + HttpUtility.UrlEncode(_Attachment);&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;        mail += &lt;span style="color: #006080"&gt;"&amp;amp;message="&lt;/span&gt; + HttpUtility.UrlEncode(_MailText);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;h3&gt;5. Making the Web Request (HTTP)&lt;/h3&gt;

&lt;p&gt;Thanks to &lt;a href="http://www.fiddler2.com/"&gt;fiddler&lt;/a&gt;, I was able to analyse the details of the contents that are posted to the Bugtracker.NET. The tool downloadable with BugTracker.NET called &lt;b&gt;bt2312&lt;/b&gt; is written in C++. I translated part of it to C# and luckily .NET has very interesting libraries which allow you to perform most of the things out of the box.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Catchingunhandledexceptionsandsendin.NET_AA5F/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Catchingunhandledexceptionsandsendin.NET_AA5F/clip_image006_62c2864d-0a16-4182-a1b6-4158d7c4a43c.gif" width="295" height="181" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fiddler enables you to inspect your web requests and that was helpful, because after i inspected the web requests from &lt;b&gt;bt2312&lt;/b&gt; i was able to replicate the behaviour.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Catchingunhandledexceptionsandsendin.NET_AA5F/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Catchingunhandledexceptionsandsendin.NET_AA5F/clip_image008_08be5a3d-518a-442f-9ce4-e1ed348bba75.gif" width="540" height="272" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The labels above indicate the steps that have been made during the web request.&lt;/p&gt;

&lt;p&gt;1. The application sends the data using HTTP.&lt;/p&gt;

&lt;p&gt;2. The data sent (as text).&lt;/p&gt;

&lt;p&gt;3. The response.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; SendBugReport()&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Success = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;     ASCIIEncoding encoding = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ASCIIEncoding();&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] buffer = encoding.GetBytes(mail);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Prepare web request...&lt;/span&gt;&lt;br /&gt;     HttpWebRequest myRequest =&lt;br /&gt;           (HttpWebRequest)WebRequest.Create(_BugUrl);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// We use POST ( we can also use GET )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;     myRequest.Method = &lt;span style="color: #006080"&gt;"POST"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Set the content type to a FORM&lt;/span&gt;&lt;br /&gt;     myRequest.ContentType = &lt;span style="color: #006080"&gt;"application/x-www-form-urlencoded"&lt;/span&gt;;&lt;br /&gt;     myRequest.UserAgent = Application.ProductName;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Get length of content&lt;/span&gt;&lt;br /&gt;     myRequest.ContentLength = buffer.Length;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Get request stream&lt;/span&gt;&lt;br /&gt;     Stream newStream = myRequest.GetRequestStream();&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Send the data.&lt;/span&gt;&lt;br /&gt;     newStream.Write(buffer, 0, buffer.Length);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Close stream&lt;/span&gt;&lt;br /&gt;     newStream.Close();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable.&lt;/span&gt;&lt;br /&gt;     HttpWebResponse myHttpWebResponse = (HttpWebResponse)myRequest.GetResponse();&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Display the contents of the page to the console.&lt;/span&gt;&lt;br /&gt;     Stream streamResponse = myHttpWebResponse.GetResponseStream();&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Get stream object&lt;/span&gt;&lt;br /&gt;     StreamReader streamRead = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StreamReader(streamResponse);&lt;br /&gt;     Char[] readBuffer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Char[256];&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Read from buffer&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; count = streamRead.Read(readBuffer, 0, 256);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (count &amp;gt; 0)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color: #008000"&gt;// get string&lt;/span&gt;&lt;br /&gt;         String resultData = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; String(readBuffer, 0, count);&lt;br /&gt;         &lt;span style="color: #008000"&gt;// Write the data&lt;/span&gt;&lt;br /&gt;         Success = resultData.Contains(&lt;span style="color: #006080"&gt;"OK:"&lt;/span&gt;);&lt;br /&gt;         Console.WriteLine(resultData);&lt;br /&gt;         &lt;span style="color: #008000"&gt;// Read from buffer&lt;/span&gt;&lt;br /&gt;         count = streamRead.Read(readBuffer, 0, 256);&lt;br /&gt;&lt;br /&gt;     }&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Release the response object resources.&lt;/span&gt;&lt;br /&gt;     streamRead.Close();&lt;br /&gt;     streamResponse.Close();&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #008000"&gt;// Close response&lt;/span&gt;&lt;br /&gt;     myHttpWebResponse.Close();&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Success;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;I have attached the Bug.cs class which contains all the code for creating a Bug report and sending it to and BugTracker.NET server. Apologies, i have not put a lot of comments in my code, if i revise this post i will probably do something about it. &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:a7fa57cd-f347-465c-a2da-0b48c508e191" class="wlWriterEditableSmartContent"&gt;&lt;p&gt;Download &lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/malisancube/WindowsLiveWriter/Catchingunhandledexceptionsandsendin.NET_AA5F/Bug_1.cs" target="_blank"&gt;Bug.cs&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132418"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132418" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/132418.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/05/26/catching-unhandled-exceptions-and-sending-them-to-bugtracker.net.aspx</guid>
            <pubDate>Wed, 27 May 2009 00:43:26 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/132418.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/05/26/catching-unhandled-exceptions-and-sending-them-to-bugtracker.net.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/132418.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/132418.aspx</trackback:ping>
        </item>
        <item>
            <title>Developing extensible applications (Plugin Frameworks and MEF)</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/04/21/the-managed-extensibility-framework.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;In last few months i have been looking into a number of technologies, methodologies and tricks on how i can design and expedite the development of the EMR software. Some of the critical success factors of this EMR were extensibility because the institution has a huge research component and many research studies have various requirements and new ones come through anytime. Therefore, the EMR architecture is supposed to allow the developer to simply create a plug-in using a VS template and simply add his/her new business objects and compile it and add it to the plug-in folder so it can be loaded by the shell application at runtime.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;We also used the Krypton Suite for our user interface. We bought the with source, and we modified the components so that they expose the KryptonRibbonGroup, KryptonRibbon, KryptonRibbonTab and KryptonRibbonRecentDoc. These make it easy for us to create ribbon elements in plug-ins and the shell application will register them at runtime automatically.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;While i was doing my research i stumbled on the managed Extensibility Framework (&lt;/font&gt;&lt;a title="http://www.codeplex.com/MEF" href="http://www.codeplex.com/MEF"&gt;&lt;font size="2"&gt;http://www.codeplex.com/MEF&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;) from Microsoft, and think it is really cool. I particularly like that fact that you can use metadata(attributes) to define dependencies in your architecture and those get satisfied at runtime.  There is also more stuff on &lt;/font&gt;&lt;a title="http://www.codeplex.com/MEFContrib" href="http://www.codeplex.com/MEFContrib"&gt;&lt;font size="2"&gt;http://www.codeplex.com/MEFContrib&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; that is interesting about MEF.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In the next couple of weeks i will be frequently blogging about my experiences in working with my custom plug-in framework and my understanding of MEF why i think it has a place in the future of software applications that need to evolve. I will also put my thoughts around what i think would be good as cosmetics or syntactic sugar in MEF and features that i think are vital for my kind of applications.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Cheers!&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4203dab8-3ed6-42f1-950a-21098217ef76" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Krypton" rel="tag"&gt;Krypton&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Reflection" rel="tag"&gt;Reflection&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Managed+Extensible+Framework" rel="tag"&gt;Managed Extensible Framework&lt;/a&gt;,&lt;a href="http://technorati.com/tags/EMR" rel="tag"&gt;EMR&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Plugin+Framework" rel="tag"&gt;Plugin Framework&lt;/a&gt;,&lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131361"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131361" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/131361.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/04/21/the-managed-extensibility-framework.aspx</guid>
            <pubDate>Wed, 22 Apr 2009 09:56:12 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/131361.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/04/21/the-managed-extensibility-framework.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/131361.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/131361.aspx</trackback:ping>
        </item>
        <item>
            <title>Using lambda or LINQ for pivot tables</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/04/21/using-lambda-or-linq-for-pivot-tables.aspx</link>
            <description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;In should say that the first time I looked lambda and linq, making pivot tables was not the main thing I thought about. After helping a few people including one at the msdn (&lt;a href="http://is.gd/oG8q"&gt;http://is.gd/oG8q&lt;/a&gt;) social site, I realized that I also needed to use the lambda in my own EMR project. &lt;/p&gt;  &lt;p&gt;The problem was to have the lab data of a patient transformed into a pivot table and some of the data summarized by averaging or counting.&lt;/p&gt;  &lt;p&gt;I had the data in the table in the following format.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;   &lt;/p&gt;&lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="72"&gt;           &lt;p&gt;&lt;b&gt;PatientID&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="48"&gt;           &lt;p&gt;&lt;b&gt;TestNo&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="60"&gt;           &lt;p&gt;&lt;b&gt;TestName&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="72"&gt;           &lt;p&gt;&lt;b&gt;TestVar&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="60"&gt;           &lt;p&gt;&lt;b&gt;Result&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="84"&gt;           &lt;p&gt;&lt;b&gt;ResultUnit&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="156"&gt;           &lt;p&gt;&lt;b&gt;CollectedDate&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="72"&gt;           &lt;p&gt;1&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="48"&gt;           &lt;p&gt;1010&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="60"&gt;           &lt;p&gt;CBC2&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="72"&gt;           &lt;p&gt;LYABS&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="60"&gt;           &lt;p&gt;2.0&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="84"&gt;           &lt;p&gt;10^3 /uL&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="156"&gt;           &lt;p&gt;1/6/2008 12:00:00 AM&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="72"&gt;           &lt;p&gt;1&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="48"&gt;           &lt;p&gt;1010&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="60"&gt;           &lt;p&gt;CBC2&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="72"&gt;           &lt;p&gt;MCHC&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="60"&gt;           &lt;p&gt;33.4&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="84"&gt;           &lt;p&gt;g/dL&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="156"&gt;           &lt;p&gt;1/6/200812:00:00 AM&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;   &lt;p&gt; &lt;/p&gt;  &lt;p&gt;I then had to write a linq expression to produce the following results.    &lt;/p&gt;&lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;&lt;b&gt;Patient&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;b&gt;TestNo&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;b&gt;CollectedDate&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;b&gt;MCHC&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;b&gt;LYABS&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;b&gt;TotalTests&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;1&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;1010&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;9/30/2008 12:00:00 AM&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;32.8&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;1.9&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;19&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;1&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;1010&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;1/6/2008 12:00:00 AM&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;33.4&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;2.0&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;21&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;1&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;1010&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;3/3/2008 12:00:00 AM&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;i&gt;null&lt;/i&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;i&gt;null&lt;/i&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;1&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;1&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;1010&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;7/2/2008 12:00:00 AM&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;33.0&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;2.2&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;21&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt; &lt;/td&gt;          &lt;td&gt; &lt;/td&gt;          &lt;td&gt; &lt;/td&gt;          &lt;td&gt; &lt;/td&gt;          &lt;td&gt; &lt;/td&gt;          &lt;td&gt; &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;   &lt;p&gt;The linq was as follows.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;labResults = &lt;span style="color: blue"&gt;from &lt;/span&gt;lab &lt;span style="color: blue"&gt;in &lt;/span&gt;CoreLabResults
                 &lt;span style="color: blue"&gt;where &lt;/span&gt;lab.Patient == 8
                 &lt;span style="color: blue"&gt;group &lt;/span&gt;lab &lt;span style="color: blue"&gt;by new &lt;/span&gt;{ lab.Patient, lab.TestNo, lab.CollectedDate }
                     &lt;span style="color: blue"&gt;into &lt;/span&gt;labtests
                     &lt;span style="color: blue"&gt;select new
                     &lt;/span&gt;{
                         labtests.Key.Patient,
                         labtests.Key.TestNo,
                         labtests.Key.CollectedDate,
                         MCHC = labtests.Where(lab =&amp;gt; lab.TestVar == &lt;span style="color: #a31515"&gt;"MCHC"&lt;/span&gt;).FirstOrDefault().Result,
                         LYABS = labtests.Where(lab =&amp;gt; lab.TestVar == &lt;span style="color: #a31515"&gt;"LYABS"&lt;/span&gt;).FirstOrDefault().Result,
                         TotalTests = labtests.Count()
                     }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The lambda expression for the above was be as follows&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;labResults = CoreLabResults
    .Where(lab =&amp;gt; lab.Patient == 8)
    .GroupBy(lab =&amp;gt;
            &lt;span style="color: blue"&gt;new
            &lt;/span&gt;{
                Patient = lab.Patient,
                AccessionNo = lab.AccessionNo,
                CollectedDate = lab.CollectedDate
            }
            )
    .Select(labtests =&amp;gt;
            &lt;span style="color: blue"&gt;new
            &lt;/span&gt;{
                Patient = labtests.Key.Patient,
                AccessionNo = labtests.Key.TestNo,
                CollectedDate = labtests.Key.CollectedDate,
                MCHC = labtests.Where(lab =&amp;gt; (lab.TestVar == &lt;span style="color: #a31515"&gt;"MCHC"&lt;/span&gt;)).FirstOrDefault().Result,
                LYABS = labtests.Where(lab =&amp;gt; (lab.TestVar == &lt;span style="color: #a31515"&gt;"LYABS"&lt;/span&gt;)).FirstOrDefault().Result,
                TotalTests = labtests.Count()
            }
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I still need to find out how I can replace the column names like “MCHC” by computed ones. I may probably need to use the expression trees to dynamically create lambda expressions that have variable number of columns. E.g. in financial statements - I would not want to hardcode column names of each financial period year/quarter.&lt;/p&gt;

&lt;p&gt;Apologies – syntax highlighting using Live writer is hell.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131358"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131358" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/131358.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/04/21/using-lambda-or-linq-for-pivot-tables.aspx</guid>
            <pubDate>Wed, 22 Apr 2009 08:55:39 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/131358.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/04/21/using-lambda-or-linq-for-pivot-tables.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/131358.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/131358.aspx</trackback:ping>
        </item>
        <item>
            <title>Ready for Windows  Could Computing</title>
            <category>Windows Azure</category>
            <link>http://geekswithblogs.net/malisancube/archive/2009/02/05/ready-for-windows--could-computing.aspx</link>
            <description>I have been allocated an account in Windows Azure Developer Portal for CTP - and very excited. Now i'm looking into the corridors of Windows Azures and downloading the SDKs. &lt;br /&gt;
&lt;br /&gt;
Am looking at these sites&lt;br /&gt;
&lt;br /&gt;
Deploying a Servce on Windows Azure&lt;br /&gt;
&lt;a href="javascript:void(0);/*1233902246518*/"&gt;http://msdn.microsoft.com/en-us/library/dd203057.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Windows Azure SDK&lt;br /&gt;
&lt;a href="javascript:void(0);/*1233902309216*/"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=BB893FB0-AD04-4FE8-BB04-0C5E4278D3E9&amp;amp;displaylang=en&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Microsoft SQL Data Services SDK&lt;br /&gt;
&lt;a href="javascript:void(0);/*1233902454104*/"&gt;http://go.microsoft.com/fwlink/?LinkID=129449&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Using Microsoft ADO.NET Data Services&lt;br /&gt;
&lt;a href="javascript:void(0);/*1233902528178*/"&gt;http://msdn.microsoft.com/en-us/library/cc907912.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Microsoft SQL Data Services SDK&lt;br /&gt;
&lt;a href="javascript:void(0);/*1233902462761*/"&gt;http://go.microsoft.com/fwlink/?LinkID=129448&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks to the &lt;font color="#888888"&gt;Azure Services Platform Team  &lt;/font&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129240"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129240" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/129240.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa Langton Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/02/05/ready-for-windows--could-computing.aspx</guid>
            <pubDate>Fri, 06 Feb 2009 06:44:15 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/129240.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/02/05/ready-for-windows--could-computing.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/129240.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/129240.aspx</trackback:ping>
        </item>
        <item>
            <title>CopyAsHTML Visual Studio Plugin</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/01/28/copyashtml-visual-studio-plugin.aspx</link>
            <description>I was very delighted when i found the CopyAsHTML tool on http://www.jtleigh.com/people/colin/software/CopySourceAsHtml/.&lt;br /&gt;
It just made me think about going through my entire list of blogs postings, to edit them so the code looks ok.&lt;br /&gt;
&lt;br /&gt;
Thanks to  &lt;a href="http://www.jtleigh.com/people/colin/"&gt;Colin Coller&lt;/a&gt; the developer of this great tool. Very ideal for bloggers.&lt;br /&gt;
&lt;br /&gt;
Cheers.&lt;br /&gt;
&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129030"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129030" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/129030.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa Langton Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/01/28/copyashtml-visual-studio-plugin.aspx</guid>
            <pubDate>Wed, 28 Jan 2009 14:13:55 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/129030.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/01/28/copyashtml-visual-studio-plugin.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/129030.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/129030.aspx</trackback:ping>
        </item>
        <item>
            <title>Visual Studio 2008 - Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER) whille adding components ot the toolbox</title>
            <link>http://geekswithblogs.net/malisancube/archive/2009/01/28/visual-studio-2008---exception-from-hresult-0x8001010a-rpc_e_servercall_retrylater-whille.aspx</link>
            <description>&lt;span id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"&gt; I have encountered a number of errors with visual studio 2008, which i'm now getting convinced are bugs. The first i will talk about is the Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)&lt;br /&gt;
&lt;br /&gt;
The reason i think it is a bug in VS2008 is the inconsistencies around it. The code below is supposed to create Toolbox items based on some assemblies that i add into the Assembly cache.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; RunCreator(&lt;span style="color: rgb(43, 145, 175);"&gt;DTE&lt;/span&gt; dte)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;if&lt;/span&gt; (DllFileList.Count &amp;lt; 1)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Could not find DLLs!"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: blue;"&gt;return&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Creating context for templates."&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;string&lt;/span&gt; tempProjPath = &lt;span style="color: rgb(43, 145, 175);"&gt;Path&lt;/span&gt;.Combine(&lt;span style="color: rgb(43, 145, 175);"&gt;Path&lt;/span&gt;.GetTempPath(), &lt;span style="color: rgb(163, 21, 21);"&gt;"tempProj"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;Directory&lt;/span&gt;.Exists(tempProjPath))&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(43, 145, 175);"&gt;Directory&lt;/span&gt;.Delete(tempProjPath, &lt;span style="color: blue;"&gt;true&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"1"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;string&lt;/span&gt; fileName = ((&lt;span style="color: rgb(43, 145, 175);"&gt;Solution2&lt;/span&gt;)dte.Solution).GetProjectTemplate(&lt;span style="color: rgb(163, 21, 21);"&gt;"WindowsApplication.zip"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"CSharp"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"2"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;switch&lt;/span&gt; (fileName)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: rgb(163, 21, 21);"&gt;""&lt;/span&gt;:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    fileName = ((&lt;span style="color: rgb(43, 145, 175);"&gt;Solution2&lt;/span&gt;)dte.Solution).GetProjectTemplate(&lt;span style="color: rgb(163, 21, 21);"&gt;"WindowsApplication.zip"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"VisualBasic"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"3"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;if&lt;/span&gt; ((fileName == &lt;span style="color: blue;"&gt;null&lt;/span&gt;) || (fileName == &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Empty))&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                fileName = ((&lt;span style="color: rgb(43, 145, 175);"&gt;Solution2&lt;/span&gt;)dte.Solution).GetProjectTemplate(&lt;span style="color: rgb(163, 21, 21);"&gt;"WindowsApplication.zip"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"csharp"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Adding solution template."&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Application&lt;/span&gt;.DoEvents();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            System.Threading.&lt;span style="color: rgb(43, 145, 175);"&gt;Thread&lt;/span&gt;.Sleep(10000);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            dte.Solution.AddFromTemplate(fileName, tempProjPath, &lt;span style="color: rgb(163, 21, 21);"&gt;"temp.cproj"&lt;/span&gt;, &lt;span style="color: blue;"&gt;false&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            dte.Solution.Close(&lt;span style="color: blue;"&gt;false&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Application&lt;/span&gt;.DoEvents();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            dte.ExecuteCommand(&lt;span style="color: rgb(163, 21, 21);"&gt;"View.PropertiesWindow"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;""&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Window&lt;/span&gt; window = dte.Windows.Item(EnvDTE.&lt;span style="color: rgb(43, 145, 175);"&gt;Constants&lt;/span&gt;.vsWindowKindToolbox);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Application&lt;/span&gt;.DoEvents();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            window.Activate();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;ToolBox&lt;/span&gt; box = window.Object &lt;span style="color: blue;"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ToolBox&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;ToolBoxTabs&lt;/span&gt; tabs = box.ToolBoxTabs;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;ToolBoxTab&lt;/span&gt; tab;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                tab = FindOrCreateTab(tabs, TABLABLE, &lt;span style="color: blue;"&gt;false&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: blue;"&gt;if&lt;/span&gt; (_option == &lt;span style="color: rgb(163, 21, 21);"&gt;"install"&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: blue;"&gt;if&lt;/span&gt; (tab != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                        tab.Delete();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                        &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Deleting tab: ["&lt;/span&gt; + TABLABLE + &lt;span style="color: rgb(163, 21, 21);"&gt;"]"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Locating tab."&lt;/span&gt;); &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    tab = FindOrCreateTab(tabs, TABLABLE, &lt;span style="color: blue;"&gt;true&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    dte.ExecuteCommand(&lt;span style="color: rgb(163, 21, 21);"&gt;"View.PropertiesWindow"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;""&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    tab.Activate();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Acquiring Components."&lt;/span&gt;); &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: blue;"&gt;this&lt;/span&gt;.ComponentDataList = &lt;span style="color: blue;"&gt;this&lt;/span&gt;.GetAllComponentsData();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: blue;"&gt;if&lt;/span&gt; (ComponentDataList.Count &amp;lt; 1) &lt;span style="color: blue;"&gt;return&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"\nRegistering..."&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;ComponentData&lt;/span&gt; componentData &lt;span style="color: blue;"&gt;in&lt;/span&gt; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.ComponentDataList)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                        RegComponent(tab, componentData);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                        System.Threading.&lt;span style="color: rgb(43, 145, 175);"&gt;Thread&lt;/span&gt;.Sleep(500);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: blue;"&gt;if&lt;/span&gt; (tab != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                        tab.Delete();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                        &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Deleting tab: ["&lt;/span&gt; + TABLABLE + &lt;span style="color: rgb(163, 21, 21);"&gt;"]"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"Done..."&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: blue;"&gt;throw&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        }&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
The moment i access &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"&gt;dte get the error.&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"&gt;&lt;img alt="bug" src="/images/geekswithblogs_net/malisancube/VS2008_Bugs/VSbug.JPG" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"&gt;I have not found any solution on google and all attempts by others have not resulted in solutions. I spent the entire day trying to solve this, but as a developer i will still persist.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129025"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129025" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/129025.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa Langton Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/01/28/visual-studio-2008---exception-from-hresult-0x8001010a-rpc_e_servercall_retrylater-whille.aspx</guid>
            <pubDate>Wed, 28 Jan 2009 12:31:59 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/129025.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/01/28/visual-studio-2008---exception-from-hresult-0x8001010a-rpc_e_servercall_retrylater-whille.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/129025.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/129025.aspx</trackback:ping>
        </item>
        <item>
            <title>Further attributes - method based validation and data conversion for business objects</title>
            <category>C#</category>
            <link>http://geekswithblogs.net/malisancube/archive/2009/01/05/further-attributes---method-based-validation-and-data-conversion-for.aspx</link>
            <description>&lt;img alt="MethodValidatorsAndConverters" src="/images/geekswithblogs_net/malisancube/MainScreen.gif" width="400" height="400" /&gt;   &lt;h2&gt;1. Introduction&lt;/h2&gt;  &lt;p&gt;This is a follow-up to the &lt;a href="http://www.codeproject.com/KB/cs/AttributeBaseValidation.aspx"&gt;"&lt;/a&gt;An attribute based approach to business object validation" article in which i introduced the use attributes and reflection to validate business objects. I also promised to write another article on data converters and method based validators, and here it is. &lt;/p&gt;  &lt;h2&gt;2. Background&lt;/h2&gt;  &lt;p&gt;In this article i will use an example to show how you can validate your business object using a method based attribute and how you can convert data assigned to properties when it is saved and re-convert it when the business object is read. All this will be based on attributes. &lt;/p&gt;  &lt;p&gt;Sometimes a need arises, to store data differently from the way it is viewed. For example if you have a field which would have comments you may want to compress them on storage. This will certainly be good for your bandwidth - especially for us here in Africa.&lt;/p&gt;  &lt;h2&gt;3. The Business object&lt;/h2&gt;  &lt;p&gt;In this example lets use a &lt;code&gt;Candidate&lt;/code&gt; object. I'm assuming a company considering interviewees. &lt;/p&gt;  &lt;p&gt;I would like you to look closely at the attributes that we have used to decorate the object below. The attributes will enable validation of the business object much easier than having to write some instructions on the presentation layer. Some attributes below will help in converting the data so that it is stored differently from the way it is viewed. &lt;/p&gt;  &lt;pre lang="CS"&gt;    public class Candidate : EntityObject&lt;br /&gt;    {&lt;br /&gt;        &lt;br /&gt;        #region Constructors&lt;br /&gt;&lt;br /&gt;        public Candidate(DataContext dataContext)&lt;br /&gt;        {&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public Candidate()&lt;br /&gt;        {&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Properties&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;        /// Property that describes the FirstName of this &lt;see cref="Candidate"&gt;         &lt;br /&gt;        /// We ensure that this is unique by using a method based validator.         &lt;br /&gt;        /// &lt;/see&gt;&lt;/summary&gt;         &lt;br /&gt;        [Required]         &lt;br /&gt;        [MethodRule("Unique")]         &lt;br /&gt;        public int CandidateNo { get; set; }          &lt;br /&gt;        &lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;        /// Property that describes the Title of this &lt;see cref="Candidate"&gt;         &lt;br /&gt;        /// This property defaults to "Mr" if the user does not specify a value.         &lt;br /&gt;        /// &lt;/see&gt;&lt;/summary&gt;         &lt;br /&gt;        &lt;br /&gt;        [DefaultValue("Mr")]         &lt;br /&gt;        public string Title { get; set; }           &lt;br /&gt;        &lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;        /// Property that describes the Firstname of this &lt;see cref="Candidate"&gt;         &lt;br /&gt;        /// &lt;/see&gt;&lt;/summary&gt;         &lt;br /&gt;        [Required]         &lt;br /&gt;        public string Firstname { get; set; }          &lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;       &lt;br /&gt;        /// Property that describes the Lastname of this &lt;see cref="Candidate"&gt;         &lt;br /&gt;        /// &lt;/see&gt;&lt;/summary&gt;         &lt;br /&gt;        [Required]         &lt;br /&gt;        public string Lastname { get; set; }          &lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;        /// Property that describes the Age of this &lt;see cref="Candidate"&gt;         &lt;br /&gt;        /// &lt;/see&gt;&lt;/summary&gt;         &lt;br /&gt;        [InRange(18, 95)]         &lt;br /&gt;        [DefaultValue(30)]         &lt;br /&gt;        public int? Age { get; set; }          &lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;        /// Property that describes the RegistrationDate of this &lt;see cref="Candidate"&gt;         &lt;br /&gt;        /// We use a method to validate this property. I have placed the Validators          &lt;br /&gt;        /// in their region below.         &lt;br /&gt;        /// &lt;/see&gt;&lt;/summary&gt;         &lt;br /&gt;        [MethodRule("ValidRegistration")]         &lt;br /&gt;        public DateTime RegistrationDate { get; set; }           &lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;        /// Property that describes the CV of this &lt;see cref="Candidate"&gt;         &lt;br /&gt;        /// In this attribute we have a DataConverter which should compress the CV         &lt;br /&gt;        /// text before it is stored.         &lt;br /&gt;        ///&lt;/see&gt;&lt;/summary&gt;&lt;br /&gt;  [DataConversion(typeof(StringZipper))]         &lt;br /&gt;         public string CV { get; set; }          &lt;br /&gt;        &lt;br /&gt;        #endregion          &lt;br /&gt;        &lt;br /&gt;        #region Methods          &lt;br /&gt;        public override string ToString()         &lt;br /&gt;        {             &lt;br /&gt;            return string.Format(&lt;br /&gt;                "ObjectID: {0} \nName: {1} \nSurname : {2} \nAge: {3} \nRegistration Date: {4} \nCV: {5}",                 &lt;br /&gt;                        ObjectID, Firstname, Lastname, Age, RegistrationDate, CV);         }          &lt;br /&gt;        #endregion          &lt;br /&gt;        &lt;br /&gt;        #region Method Based Validators          &lt;br /&gt;        &lt;br /&gt;        public void ValidRegistration(object sender, ValidateEventArgs e)         &lt;br /&gt;        {             &lt;br /&gt;             e.Valid = true;              &lt;br /&gt;             if (RegistrationDate.Date &amp;lt; DateTime.Parse("01/01/2008 8:00:00"))             &lt;br /&gt;             {                 &lt;br /&gt;                 e.Valid = true;                 &lt;br /&gt;                 e.ErrorMessage = "Impossible! The client could not have registered before we started this business.";                                  &lt;br /&gt;                &lt;br /&gt;                 //Set to the minimum date - if you want                 &lt;br /&gt;                 e.Property.SetValue(this, DateTime.Parse("01/01/2008 8:00:00"), null);             &lt;br /&gt;             }         &lt;br /&gt;             &lt;br /&gt;        }          &lt;br /&gt;        &lt;br /&gt;        public void Unique(object sender, ValidateEventArgs e)         &lt;br /&gt;        {             &lt;br /&gt;             if (this.IsNew)             &lt;br /&gt;             {                 &lt;br /&gt;                // A bit of LINQ to find if we have this candidate                  &lt;br /&gt;                var query = from candidate in DataSettings.DataContext.EntityObjects.OfType&lt;candidate&gt;()&lt;br /&gt;                            where candidate.CandidateNo == this.CandidateNo&lt;br /&gt;                            select candidate;&lt;br /&gt;&lt;br /&gt;                e.Valid = query.Count() &amp;lt;= 1;&lt;br /&gt;                e.ErrorMessage = "The Candidate number must be unique.";&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/candidate&gt;&lt;/pre&gt;

&lt;p&gt;The collection of attributes included in this object are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Required&lt;/strong&gt; - To ensure that the property value is entered. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;InRange&lt;/strong&gt; - A range validator. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;DefaultValue&lt;/strong&gt; - Indicates that if value is omitted, the default will be assigned to property. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;MethodRule&lt;/strong&gt; - Executes a method specified on saving the object. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;DataConversion&lt;/strong&gt; - converts the data assigned to property using a conversion class specifed. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this example, i'm saving all my objects in a cache-like object, which i call &lt;code&gt;DataSettings.DataContext.EntityObjects&lt;/code&gt;, and i use the code below to find an object.&lt;/p&gt;

&lt;pre lang="CS"&gt;             Guid CandidateID = (Guid)dataGridView1[9, e.RowIndex].Value;&lt;br /&gt;&lt;br /&gt;            Candidate candidate = new Candidate(); //You may decide to use static methods for this&lt;br /&gt;            candidate.Load(CandidateID);&lt;br /&gt;            if (candidate != null)&lt;br /&gt;            {&lt;br /&gt;                candidateBindingSource.DataSource = candidate;&lt;br /&gt;                cVTextBox.Text = candidate.CV;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;If we save the data we would have the following.&lt;/p&gt;
&lt;img alt="Compressed" src="/images/geekswithblogs_net/malisancube/Compressed.gif" /&gt; 

&lt;h2&gt;4. The Business object Base &lt;/h2&gt;

&lt;p&gt;In this example i would like you to focus on the area where i create a delegate using &lt;code&gt;Delegate.CreateDelegate(typeof(EventHandler)...&lt;/code&gt;.&lt;/p&gt;

&lt;pre lang="CS"&gt;    public class EntityObject : IEntityObject&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        #region Internal Fields&lt;br /&gt;&lt;br /&gt;        internal Guid objectID;&lt;br /&gt;        public bool IsNew { get;  set; }&lt;br /&gt;        public bool IsDirty { get;  set; }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Public Properties&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;         &lt;br /&gt;        /// The Errors collection to keep the errors. The validation method populates this.         &lt;br /&gt;        /// &lt;/summary&gt;         &lt;br /&gt;        public readonly List&lt;error&gt; Errors = new List&lt;error&gt;();&lt;br /&gt;&lt;br /&gt;        public DataContext dataContext;&lt;br /&gt;&lt;br /&gt;        public Guid ObjectID &lt;br /&gt;        { &lt;br /&gt;            get &lt;br /&gt;            {&lt;br /&gt;                return objectID; &lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                objectID = value;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Constructors&lt;br /&gt;&lt;br /&gt;        public EntityObject()&lt;br /&gt;        {&lt;br /&gt;            if (dataContext == null)&lt;br /&gt;            {&lt;br /&gt;                if (DataSettings.DataContext == null) DataSettings.DataContext = new DataContext(); &lt;br /&gt;                this.dataContext = DataSettings.DataContext;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            //Create unique object identifier&lt;br /&gt;            objectID = Guid.NewGuid();&lt;br /&gt;            IsNew = true;&lt;br /&gt;            IsDirty = false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public EntityObject(DataContext dataContext)&lt;br /&gt;        {&lt;br /&gt;            if (dataContext == null)&lt;br /&gt;            {&lt;br /&gt;                if (DataSettings.DataContext == null) DataSettings.DataContext = new DataContext();&lt;br /&gt;                this.dataContext = DataSettings.DataContext;&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;                this.dataContext = dataContext;&lt;br /&gt;&lt;br /&gt;        }        &lt;br /&gt;        &lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;	.....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        public virtual void Validate(object sender, ValidateEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            //Initialise the error collection&lt;br /&gt;            Errors.Clear();&lt;br /&gt;&lt;br /&gt;            //Enable calling the OnValidate event before validation takes place&lt;br /&gt;            if (this.OnValidate != null) this.OnValidate(this, new ValidateEventArgs());&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                foreach (PropertyInfo prop in this.GetType().GetProperties())&lt;br /&gt;                {&lt;br /&gt;                    /* Get property value assigned to property */&lt;br /&gt;                    object data = prop.GetValue(this, null);&lt;br /&gt;&lt;br /&gt;                    #region Default Value setting&lt;br /&gt;			...	&lt;br /&gt;                    #endregion&lt;br /&gt;&lt;br /&gt;                    #region IsRequired Validation&lt;br /&gt;			...&lt;br /&gt;                    #endregion&lt;br /&gt;&lt;br /&gt;                    #region InRange Validation&lt;br /&gt;			...&lt;br /&gt;                    #endregion&lt;br /&gt;&lt;br /&gt;                    #region MethodBasedValidation&lt;br /&gt;                    /* Check if property value is Method Based Validation */&lt;br /&gt;                    foreach (object customAttribute in prop.GetCustomAttributes(typeof(MethodRuleAttribute), true))&lt;br /&gt;                    {&lt;br /&gt;                        //Create event handler dynamically&lt;br /&gt;                        EventHandler&lt;validateeventargs&gt; eventHandler = Delegate.CreateDelegate(typeof(EventHandler&lt;validateeventargs&gt;), this, &lt;br /&gt;                            (customAttribute as MethodRuleAttribute).ValidationMethod) as EventHandler&lt;validateeventargs&gt;;&lt;br /&gt;                        ValidateEventArgs args = new ValidateEventArgs(prop, string.Format("Value assigned to {0} is invalid.", prop.Name));&lt;br /&gt;&lt;br /&gt;                        eventHandler(this, args);  // Execute event handler&lt;br /&gt;                        if (!args.Valid)&lt;br /&gt;                        {&lt;br /&gt;                            Errors.Add(new Error(this, prop.Name, args.ErrorMessage));&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                    #endregion&lt;br /&gt;&lt;br /&gt;                    #region Data Converters&lt;br /&gt;&lt;br /&gt;                    /* Check if property value is required */&lt;br /&gt;                    foreach (object customAttribute in prop.GetCustomAttributes(typeof(DataConversionAttribute), true))&lt;br /&gt;                    {&lt;br /&gt;                        Type conversionType = (customAttribute as DataConversionAttribute).ConverterType;&lt;br /&gt;                        prop.SetValue(this, Converter.Instance(conversionType).Change.ToPersistentType(data), null);&lt;br /&gt;                    }&lt;br /&gt;&lt;br /&gt;                    #endregion&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            catch (Exception ex)&lt;br /&gt;            {&lt;br /&gt;                //&lt;br /&gt;                throw new Exception("Could not validate Object!", ex);&lt;br /&gt;            }&lt;br /&gt;            finally&lt;br /&gt;            {&lt;br /&gt;                //Enable calling the OnValidated event after validation has taken place&lt;br /&gt;                if (this.OnValidated != null) this.OnValidated(this, new ValidateEventArgs());&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/validateeventargs&gt;&lt;/validateeventargs&gt;&lt;/validateeventargs&gt;&lt;/error&gt;&lt;/error&gt;&lt;/pre&gt;

&lt;h2&gt;5. Method Based validators.&lt;/h2&gt;

&lt;p&gt;A delegate is a pointer to a method or event handler. &lt;/p&gt;

&lt;p&gt;The .NET framework has a very interesting feature which enables us to create delegates at runtime and bind them to event handlers. &lt;/p&gt;

&lt;p&gt;The following is the algorithm for a method based validator&lt;/p&gt;

&lt;ul&gt;(a) Go to next Property.
  &lt;br /&gt;(b) If not exists exit.

  &lt;br /&gt;(c) Find associated attributes

  &lt;br /&gt;(d) If the attribute is a MethodValidator proceed, else jump to (i).

  &lt;br /&gt;(e) Create delegate, bind it to the method indicated on MethodValidator.

  &lt;br /&gt;(f) Create new Event arguments of validation type.

  &lt;br /&gt;(g) Execute associated eventhandler, using the event arguments.

  &lt;br /&gt;(h) If result on the event arguments is not valid, add Error to this.Errors collection.

  &lt;br /&gt;(i) Go to (a).

  &lt;br /&gt;&lt;/ul&gt;

&lt;p&gt;The main thing behing the method based validator is the ability to bind the evant at runtime to a property, and thanks again to reflection. We can find attributes associated with a property and then we create a delegate which points to the event handler presented at the attribute. We then invoke the eventhandler using event arguments, which would then help us to obtain response from the method call. The response from the event handler is then used to add associated &lt;code&gt;Error&lt;/code&gt; to the &lt;code&gt;Errors&lt;/code&gt; collection of &lt;code&gt;this&lt;/code&gt; object.&lt;/p&gt;

&lt;pre lang="CS"&gt;                       //Create delegate and map it to ValidationMethod of current property&lt;br /&gt;                        EventHandler&lt;validateeventargs&gt; eventHandler = Delegate.CreateDelegate(typeof(EventHandler&lt;validateeventargs&gt;), this, &lt;br /&gt;                                        (customAttribute as MethodRuleAttribute).ValidationMethod) as EventHandler&lt;validateeventargs&gt;;&lt;br /&gt;&lt;br /&gt;                       //Create event arguments which we will inject into handler, and then review the modifications on it&lt;br /&gt;                        ValidateEventArgs args = new ValidateEventArgs(prop, string.Format("Value assigned to {0} is invalid.", prop.Name));&lt;br /&gt;&lt;br /&gt;                        eventHandler(this, args);  // Execute event handler through the delegate&lt;br /&gt;                        if (!args.Valid)           // Read argument after it has been affected by the event handler&lt;br /&gt;                        {&lt;br /&gt;                            Errors.Add(new Error(this, prop.Name, args.ErrorMessage));&lt;br /&gt;                        }&lt;br /&gt;&lt;br /&gt;&lt;/validateeventargs&gt;&lt;/validateeventargs&gt;&lt;/validateeventargs&gt;&lt;/pre&gt;

&lt;p&gt;For more information on dynamic delagate creation, consult the MDSN documentation (&lt;a href="http://msdn.microsoft.com/en-us/library/53cz7sc6.aspx"&gt;here&lt;/a&gt;). &lt;/p&gt;

&lt;h2&gt;6. The Data Converters&lt;/h2&gt;

&lt;p&gt;The data converters enable us to change the data before it is stored. They inherit from the &lt;code&gt;DataConverter&lt;/code&gt; class below.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;We made the methods virtual so that you can override them for any implementation of conversion. The &lt;code&gt;ToPersistentType(object value)&lt;/code&gt; is to enable conversion to storage type while &lt;code&gt;FromPersistentType(object value)&lt;/code&gt; converts data back to viewable type.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre lang="CS"&gt;     public class DataConverter&lt;br /&gt;    {&lt;br /&gt;        public virtual object ToPersistentType(object value)&lt;br /&gt;        {&lt;br /&gt;            throw new NotImplementedException();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public virtual object FromPersistentType(object value)&lt;br /&gt;        {&lt;br /&gt;            throw new NotImplementedException();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;The class below is one data converter, that may be used to compress string data. You may decide to create another one to compress other data types or encrypt certain data when its stored. That reminds me of a payroll application which i built and the clients did not want the column which stores salary to be readable to database admnistrators.&lt;/p&gt;

&lt;pre lang="CS"&gt;     class StringZipper: DataConverter&lt;br /&gt;    {&lt;br /&gt;        public override object ToPersistentType(object value)&lt;br /&gt;        {&lt;br /&gt;            return value == null ? null : (object)Zipper.Compress((string)value);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override object FromPersistentType(object value)&lt;br /&gt;        {&lt;br /&gt;            return value == null ? null : (object)Zipper.Decompress((string)value);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Code below shows how you can load the and object within the base class.&lt;/p&gt;

&lt;pre lang="CS"&gt;         public void Load(Guid entityObjectID)&lt;br /&gt;        {&lt;br /&gt;            EntityObject entityObject = new EntityObject(DataSettings.DataContext);&lt;br /&gt;            entityObject = dataContext.Load(entityObjectID);&lt;br /&gt;            entityObject.IsNew = false;&lt;br /&gt;            entityObject.IsDirty = false;&lt;br /&gt;&lt;br /&gt;            if (entityObject != null)&lt;br /&gt;            {&lt;br /&gt;                foreach (PropertyInfo prop in entityObject.GetType().GetProperties())&lt;br /&gt;                {&lt;br /&gt;                    /* Get property value assigned to property */&lt;br /&gt;                    object data = prop.GetValue(entityObject, null);&lt;br /&gt;&lt;br /&gt;                    #region Data Converters&lt;br /&gt;&lt;br /&gt;                    if ((prop.Attributes == PropertyAttributes.None) &amp;amp;&amp;amp; (data != null))&lt;br /&gt;                        prop.SetValue(this, data, null);&lt;br /&gt;                    &lt;br /&gt;                    /* Check if property value is required */&lt;br /&gt;                    foreach (object customAttribute in prop.GetCustomAttributes(typeof(DataConversionAttribute), true))&lt;br /&gt;                    {&lt;br /&gt;                        Type conversionType = (customAttribute as DataConversionAttribute).ConverterType;&lt;br /&gt;                        prop.SetValue(this, Converter.Instance(conversionType).Change.FromPersistentType(data), null);&lt;br /&gt;                    }&lt;br /&gt;                    #endregion&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine("Could not find object!");&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;h2&gt;7. Techniques used in this article&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Reflection &lt;/li&gt;

  &lt;li&gt;Generics &lt;/li&gt;

  &lt;li&gt;Anonymous types &lt;/li&gt;

  &lt;li&gt;Delegates / Dynamic Delegates &lt;/li&gt;

  &lt;li&gt;LINQ &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;8. Challenges and Limitations&lt;/h2&gt;

&lt;ul&gt;(a) Using reflection .SetValue() on attributes without setters specified.
  &lt;br /&gt;(b) DataBinding for convertable properties is not supported, else the user will see some garbled text on some controls.

  &lt;br /&gt;(c) I don't know whether to call it a limitation - typesafety and generics are not available on attributes.

  &lt;br /&gt;&lt;img alt="" src="/images/geekswithblogs_net/malisancube/genericattributes.JPG" width="698" height="138" genericattributes.jpg="genericattributes.jpg" /&gt; &lt;/ul&gt;

&lt;h2&gt;9. History&lt;/h2&gt;

&lt;p&gt;Published on 03/01/2009, follow-up of &lt;a href="http://www.codeproject.com/KB/cs/AttributeBaseValidation.aspx"&gt;Attribute based validation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;10. Source Code&lt;/h2&gt;

&lt;p&gt;All source code for this article is available for download from &lt;a href="http://www.codeproject.com/KB/cs/MethodBasedAttributes.aspx"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:c0ad9504-97b2-4c32-a66a-dd64f07e32b3" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;,&lt;a href="http://technorati.com/tags/.NET" rel="tag"&gt;.NET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Reflection" rel="tag"&gt;Reflection&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=128366"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=128366" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/128366.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2009/01/05/further-attributes---method-based-validation-and-data-conversion-for.aspx</guid>
            <pubDate>Mon, 05 Jan 2009 17:05:50 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/128366.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2009/01/05/further-attributes---method-based-validation-and-data-conversion-for.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/128366.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/128366.aspx</trackback:ping>
        </item>
        <item>
            <title>An attribute based approach to business object validation</title>
            <link>http://geekswithblogs.net/malisancube/archive/2008/12/22/an-attribute-based-approach-to-business-object-validation.aspx</link>
            <description>&lt;br /&gt;  &lt;br /&gt;&lt;img alt="Attribute based validation for business objects" src="/images/geekswithblogs_net/malisancube/PersonTest.gif" width="310" height="200" /&gt;  &lt;br /&gt;  &lt;h2&gt;1. Introduction&lt;/h2&gt;  &lt;p&gt;This article shows how you can use attributes to validate your business objects. You may have had to write tones of code to validate your business objects without taking advantage of attributes. The value of attributes comes when you need to apply the same rules on a number of properties and the only thing you have to do is to decorate your property accordingly. For other articles on attribute based validation please check the &lt;a href="http://visualstudiomagazine.com/features/article.aspx?editorialsid=1317"&gt;Visual Studio Magazine &lt;/a&gt;and &lt;a href="AttributeValidation.aspx"&gt;Ennis Ray Lynch, Jr&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;2. Background&lt;/h2&gt;  &lt;p&gt;The .NET compiler enables us to richly embed metadata into an assembly, which can be accessed at a later time by reflection. Attributes are decorative clauses that can be placed on either classes, interfaces, methods, assemblies, modules or other items. They become part of the assembly metadata and can be used to assign rules to the compiler or enable developers to reuse code to perform various operations including validation, tracing and type conversion. Attributes are inherited from the &lt;code&gt;System.Attribute&lt;/code&gt; class &lt;/p&gt;  &lt;p&gt;Examples of attributes/p&amp;gt; &lt;/p&gt;  &lt;pre lang="CS"&gt;[Serializable, XmlRoot(Namespace = "www.idi.ac.ug")]&lt;br /&gt;public class Person : EntityObject {&lt;br /&gt;     	[XmlAttribute]&lt;br /&gt;	public string Firstname {get ; set;}&lt;br /&gt;&lt;br /&gt;     	[XmlAttribute]&lt;br /&gt;	public string Lastname {get ; set;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
Some attributes that are commonly used include 

&lt;p&gt;&lt;code&gt;[Obsolete]&lt;/code&gt;Tells compiler to issue a warning because the decorated method is obsolete.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[Serializable]&lt;/code&gt; Tells compiler that the object is can be serialized to some storage, as Xml, Text or Binary.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[Assembly: ]&lt;/code&gt; These are assembly level attributes that are applied on the entire assembly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[DefaultValue]&lt;/code&gt; this is used to give a default value.&lt;/p&gt;

&lt;p&gt;In our case we would like to see how we can build our own custom attributes which we can use to make business object validation easier. The usability of attributes would surely save you time, code and the stress of having to individually validate each property of a business object.&lt;/p&gt;

&lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;
  &lt;p style="margin: 0px"&gt;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Person class.&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; This class represents the person &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Author: Malisa Ncube&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Person&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;EntityObject&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;{&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Property that describes the Title of this &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;see cref="Person"&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/see&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    [DefaultValue(&lt;span style="color: rgb(163,21,21)"&gt;"Mr"&lt;/span&gt;)]&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Title { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Property that describes the FirstName of this &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;see cref="Person"&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/see&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    [Required]&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; FirstName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Property that describes the LastName of this &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;see cref="Person"&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/see&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    [Required(ErrorMessage = &lt;span style="color: rgb(163,21,21)"&gt;"LastName must have a value"&lt;/span&gt;)]&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; LastName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Property that describes the Age of this &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;see cref="Person"&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/see&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    [InRange(18, 95)]&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    [DefaultValue(30)]&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt;? Age { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Validate(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, ValidateEventArgs e)&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;base&lt;/span&gt;.Validate(sender, e);&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: green"&gt;//Custom business rules&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;this&lt;/span&gt;.Age == 25)&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        { Errors.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; Error(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;"Person"&lt;/span&gt;, &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                     &lt;span style="color: rgb(163,21,21)"&gt;"A person cannot be 25 years of age!"&lt;/span&gt;)); }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;}&lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;3. The business object&lt;/h2&gt;

&lt;p&gt;Consider a business object called &lt;code&gt;Person&lt;/code&gt; which we have decided inherits from the base class &lt;code&gt;EntityObject&lt;/code&gt;. We have made the base class to implement the &lt;code&gt;IEntityObject&lt;/code&gt; interface although it in not vital for this article. The attributes used here are [Required], [InRange] and [DefaultValue] &lt;/p&gt;

&lt;pre lang="CS"&gt; &lt;/pre&gt;

&lt;p&gt;In the calling method, I would like to instantiate the &lt;code&gt;Person&lt;/code&gt; object and ensure that on &lt;em&gt;object.&lt;/em&gt;&lt;code&gt;Save()&lt;/code&gt; method which is provided by the base class, I validate the object. There are other approaches you may use, e.g. immediate validation when a property have been changed. I have decided to defer validation to the end because the process involves reflection, which can be expensive.&lt;/p&gt;

&lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;
  &lt;p style="margin: 0px"&gt;          &lt;span style="color: green"&gt;// Create new instance of the Person class&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            Person person = &lt;span style="color: blue"&gt;new&lt;/span&gt; Person();&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;           &lt;span style="color: green"&gt;//Assign values to properties&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;           person.Firstname = &lt;span style="color: rgb(163,21,21)"&gt;"John"&lt;/span&gt;;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;           person.Lastname = &lt;span style="color: rgb(163,21,21)"&gt;"Doe"&lt;/span&gt;;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;           person.Age = 15; &lt;span style="color: green"&gt;//Should cause the object to be invalid and fail to save&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;           &lt;span style="color: blue"&gt;string&lt;/span&gt; errMsg = &lt;span style="color: rgb(163,21,21)"&gt;"Could not save Person!\n\n"&lt;/span&gt;; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!person.Save())&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: green"&gt;//Collect all error messages into one error string&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(Error err &lt;span style="color: blue"&gt;in&lt;/span&gt; person.Errors) &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    errMsg += err.Message + &lt;span style="color: rgb(163,21,21)"&gt;"\n"&lt;/span&gt;;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                MessageBox.Show(errMsg, &lt;span style="color: rgb(163,21,21)"&gt;"Error"&lt;/span&gt;, MessageBoxButtons.OK, &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                           MessageBoxIcon.Exclamation);&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;else&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: green"&gt;//We show the following message if the person object is valid&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                MessageBox.Show(&lt;span style="color: rgb(163,21,21)"&gt;"Person = Valid"&lt;/span&gt;);&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;4. The attributes&lt;/h2&gt;

&lt;p&gt;Let’s have a look at the attribute classes presented below. We will begin with the &lt;code&gt;[Required]&lt;/code&gt; attribute and i should quickly ask you to note that the actual class name is &lt;code&gt;RequiredAttribute&lt;/code&gt; and .NET lets you write it nicely as &lt;code&gt;[Required]&lt;/code&gt; instead of &lt;code&gt;[RequiredAttribute]&lt;/code&gt; although it will still work.&lt;/p&gt;

&lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;
  &lt;p style="margin: 0px"&gt;        [&lt;span style="color: rgb(43,145,175)"&gt;AttributeUsage&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;AttributeTargets&lt;/span&gt;.Property, AllowMultiple = &lt;span style="color: blue"&gt;false&lt;/span&gt;)]&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;RequiredAttribute&lt;/span&gt; : System.&lt;span style="color: rgb(43,145,175)"&gt;Attribute&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; required;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; errorMessage;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; Required&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;get&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    &lt;span style="color: blue"&gt;return&lt;/span&gt; required;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;set&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    required = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ErrorMessage&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;get&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    &lt;span style="color: blue"&gt;return&lt;/span&gt; errorMessage;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;set&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    errorMessage = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;public&lt;/span&gt; RequiredAttribute()&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                required = &lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;public&lt;/span&gt; RequiredAttribute(&lt;span style="color: blue"&gt;bool&lt;/span&gt; required)&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.required = required;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;public&lt;/span&gt; RequiredAttribute(&lt;span style="color: blue"&gt;string&lt;/span&gt; errorMessage)&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.errorMessage = errorMessage;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        }&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;In the above &lt;code&gt;Required&lt;/code&gt; attribute, the&lt;code&gt;[AttributeUsage]&lt;/code&gt;, is an attribute of an attribute - interesting isn't it? It enables you to determine or restrict where the attribute may be used, and in my example above we can only use the Required attribute on properties. The &lt;code&gt;AttributeTarget&lt;/code&gt; is a enum in which you can choose the scope of where this attribute can be used. The default is All, however you can have &lt;code&gt;Assembly, Class, Constructor, Delegate, Enum, Event, Field, Interface, method, Parameter, Property, ReturnValue &lt;/code&gt;and &lt;code&gt;struct&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can use &lt;code&gt;AllowMultiple&lt;/code&gt; parameter of the &lt;code&gt;AttributeUsage&lt;/code&gt; to determine whether the same attribute can be used more than once on the same target. In this case we can only have the [Required] attribute only once on a property.&lt;/p&gt;

&lt;p&gt;Attributes can only have constants&lt;/p&gt;

&lt;h2&gt;5. The Business Object Base&lt;/h2&gt;

&lt;p&gt;I decided to place a public &lt;code&gt;Errors&lt;/code&gt; collection which will keep errors encountered during validation. I also added event handlers that can be triggered when the validation method is executed. This enables hijacking the validation process if necessary and to inject validation rules after the object has been created. The &lt;code&gt;Validate()&lt;/code&gt; method is virtual and therefore can be overridden to allow custom business rules. This is what you would use to ensure that a Male person would not have a boolean Pregnant property set to true./p&amp;gt; &lt;/p&gt;

&lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;
  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt;      &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; EntityObject class.     &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; This Entity base class      &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Author: Malisa Ncube     &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt;     public class EntityObject : IEntityObject     &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    {                  &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;        #region&lt;/span&gt; Internal Fields         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt;          &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; The Errors collection to keep the errors. Tthe validation method populates this.         &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; List Errors = &lt;span style="color: blue"&gt;new&lt;/span&gt; List();&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;        #endregion&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;        #region&lt;/span&gt; Delegate and Events&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt;          &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: green"&gt;// OnValidateEventHandler delegate to enable injection of custom validation routines         &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;delegate&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;OnValidateEventHandler&lt;/span&gt;(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, ValidateEventArgs e);       &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;delegate&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;OnValidatedEventHandler&lt;/span&gt;(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, ValidateEventArgs e);        &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;OnValidateEventHandler&lt;/span&gt; OnValidate;         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;OnValidatedEventHandler&lt;/span&gt; OnValidated;         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        .....     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;    }  &lt;/p&gt;
&lt;/div&gt;

&lt;br /&gt;

&lt;h2&gt;6. Reflection&lt;/h2&gt;

&lt;p&gt;We use reflection and the validate method loops through all the properties looking for associated custom attributes. We then test the property value against the attribute rule, and if it violates the rule we then add an error into the Errors collection.&lt;/p&gt;

&lt;p&gt;The magic of knowing all the properties lies in the &lt;code&gt;System.Reflection namespace&lt;/code&gt;. We first will then use &lt;code&gt;PropertyInfo&lt;/code&gt; to keep all the properties of the object and &lt;code&gt;GetType.GetProperties()&lt;/code&gt; method as follows.&lt;/p&gt;
&lt;code&gt;PropertyInfo info = this.GetType().GetProperties();&lt;/code&gt; 

&lt;p&gt;We furthermore check the attributes on each property to see if it matches e.g. &lt;code&gt;RequiredAttribute&lt;/code&gt;, if it does we then check the property value for violation of attribute rules. We also provide an appropriate error message if the message was not included in the attribute declaration.&lt;/p&gt;

&lt;p&gt;The validate method of the base object &lt;code&gt;EntityObject&lt;/code&gt; is as follows&lt;/p&gt;

&lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;
  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;        #region&lt;/span&gt; Internal Fields&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt;          &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; The Errors collection to keep the errors. Tthe validation method populates this.         &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; List Errors = &lt;span style="color: blue"&gt;new&lt;/span&gt; List();&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;        #endregion&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;       .....&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt;          &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Validate method performs the validation process and allows overriding          &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;virtual&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Validate(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, ValidateEventArgs e)         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        {             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: green"&gt;//Initialise the error collection             &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            Errors.Clear();              &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: green"&gt;//Enable calling the OnValidate event before validation takes place             &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;this&lt;/span&gt;.OnValidate != &lt;span style="color: blue"&gt;null&lt;/span&gt;) &lt;span style="color: blue"&gt;this&lt;/span&gt;.OnValidate(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt; ValidateEventArgs());             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;try&lt;/span&gt;             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {                  &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (PropertyInfo info &lt;span style="color: blue"&gt;in&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.GetType().GetProperties())                 &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                {                     &lt;span style="color: green"&gt;/* Get property value assigned to property */&lt;/span&gt;                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    &lt;span style="color: blue"&gt;object&lt;/span&gt; data = info.GetValue(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;);                      &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    &lt;span style="color: green"&gt;/* Set Default value if value is empty */&lt;/span&gt;                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;object&lt;/span&gt; customAttribute &lt;span style="color: blue"&gt;in&lt;/span&gt; info.GetCustomAttributes(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(DefaultValueAttribute), &lt;span style="color: blue"&gt;true&lt;/span&gt;))                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    {                         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                        &lt;span style="color: blue"&gt;if&lt;/span&gt; (data == &lt;span style="color: blue"&gt;null&lt;/span&gt;)                         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    {                             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                        info.SetValue(&lt;span style="color: blue"&gt;this&lt;/span&gt;, (customAttribute &lt;span style="color: blue"&gt;as&lt;/span&gt; DefaultValueAttribute).Default, &lt;span style="color: blue"&gt;null&lt;/span&gt;);                             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                            data = info.GetValue(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;);                         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                        }                     }                      &lt;span style="color: green"&gt;/* Check if property value is required */&lt;/span&gt;                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;object&lt;/span&gt; customAttribute &lt;span style="color: blue"&gt;in&lt;/span&gt; info.GetCustomAttributes(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(RequiredAttribute), &lt;span style="color: blue"&gt;true&lt;/span&gt;))                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    {                         &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty((&lt;span style="color: blue"&gt;string&lt;/span&gt;)data))                         {                             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                        Errors.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; Error(&lt;span style="color: blue"&gt;this&lt;/span&gt;, info.Name,                                &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                            &lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty((customAttribute &lt;span style="color: blue"&gt;as&lt;/span&gt; RequiredAttribute).ErrorMessage) ?                                &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                            &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: rgb(163,21,21)"&gt;"{0} is required"&lt;/span&gt;, info.Name) : (customAttribute &lt;span style="color: blue"&gt;as&lt;/span&gt; RequiredAttribute).ErrorMessage));                         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    }                     }                      &lt;span style="color: green"&gt;/* Evaluate whether the property value lies within range */&lt;/span&gt;                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;object&lt;/span&gt; customAttribute &lt;span style="color: blue"&gt;in&lt;/span&gt; info.GetCustomAttributes(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(InRangeAttribute), &lt;span style="color: blue"&gt;true&lt;/span&gt;))                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                    {                          &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                                &lt;span style="color: blue"&gt;if&lt;/span&gt; (!(((&lt;span style="color: rgb(43,145,175)"&gt;IComparable&lt;/span&gt;)data).CompareTo((customAttribute &lt;span style="color: blue"&gt;as&lt;/span&gt; InRangeAttribute).Min) &amp;gt; 0) ||   !(((&lt;span style="color: rgb(43,145,175)"&gt;IComparable&lt;/span&gt;)data).CompareTo((customAttribute &lt;span style="color: blue"&gt;as&lt;/span&gt; InRangeAttribute).Max) &amp;lt; 0))                         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                                {                             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                                Errors.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; Error(&lt;span style="color: blue"&gt;this&lt;/span&gt;, info.Name,                              &lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty((customAttribute &lt;span style="color: blue"&gt;as&lt;/span&gt; InRangeAttribute).ErrorMessage) ?                              &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                                &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: rgb(163,21,21)"&gt;"{0} is out of range"&lt;/span&gt;, info.Name) : (customAttribute &lt;span style="color: blue"&gt;as&lt;/span&gt; InRangeAttribute).ErrorMessage));                         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                            }                     &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                            }                 }             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }             &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt; ex)             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {                 &lt;span style="color: green"&gt;//                 throw new Exception("Could not validate Object!", ex);             }             &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                        &lt;span style="color: blue"&gt;finally&lt;/span&gt;             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            {                 &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: green"&gt;//Enable calling the OnValidated event after validation has taken place                 &lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;this&lt;/span&gt;.OnValidated != &lt;span style="color: blue"&gt;null&lt;/span&gt;) &lt;span style="color: blue"&gt;this&lt;/span&gt;.OnValidated(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt; ValidateEventArgs());             &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            }         &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        } &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        }  &lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;7. Overriding the Validate method&lt;/h2&gt;

&lt;p&gt;Below is some code which shows how you would override the &lt;code&gt;Validate&lt;/code&gt; method of the business object and add custom validation rules. &lt;/p&gt;

&lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;
  &lt;p style="margin: 0px"&gt;   ....&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Validate(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, ValidateEventArgs e)&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        {&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;base&lt;/span&gt;.Validate(sender, e);&lt;/p&gt;

  &lt;p style="margin: 0px"&gt; &lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: green"&gt;//Custom business rules&lt;/span&gt;&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;this&lt;/span&gt;.Age == 25) { Errors.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; Error(&lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;"Person"&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;"A person cannot be 25 years of age!"&lt;/span&gt;)); }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;        }&lt;/p&gt;

  &lt;p style="margin: 0px"&gt;}&lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;8. Other Considerations&lt;/h2&gt;

&lt;p&gt;a. You may decide to have the a &lt;code&gt;Validate&lt;/code&gt; method in each attribute that takes the arguments from the reflected data and transform it into a appropriate manner. This would enable you not to worry about testing for validity of the property value on the business object but let the business object call the instance of the attribute and validate values in an identical manner.&lt;/p&gt;

&lt;p&gt;b. When you need to databind the business object on to you winforms / WPF / WebForms you may have to take advantage of the nice interfaces that are provided in the .NET framework to enable ErrorProviders inform users on invalid entries.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;IErrorInfo 
    &lt;br /&gt;INotifyPropertyChanged

    &lt;br /&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;c. You may also decide to cache the properties and their attributes on business object creation to enable better performance. This would be a best approach if you wish to do immediate validation, rather than wait until the user saves the object.&lt;/p&gt;

&lt;p&gt;d. You may decide to have more complex attributes which call delegates on validation. This would be another way that would enable you to create more robust and flexible business rules.&lt;/p&gt;

&lt;p&gt;e. Using AOP (Aspect oriented programming) frameworks like &lt;a href="http://www.postsharp.org"&gt;PostSharp &lt;/a&gt;you can add attributes to you object and perform validation, tracing and other interesting things.&lt;/p&gt;

&lt;p&gt;Please check &lt;a href="http://www.codeplex.com/ValidationAspects"&gt;Validation Aspects &lt;/a&gt;and the &lt;a href="http://www.codeplex.com/ValidationFramework"&gt;Validation Framework &lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;9. Conclusion&lt;/h2&gt;

&lt;p&gt;I hope this will help those of you who would like to understand what attribute based programming is. While writing this article i realised that there is type-safety is something as a programmer you need to look at closely. Ensure that for example you use &lt;code&gt;[DefaultValue(30)]&lt;/code&gt; rather than a string &lt;code&gt;[DefaultValue("30")]&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;10. History&lt;/h2&gt;

&lt;p&gt;* 12/22/2008: First posted.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Source code for this article is available on CodeProject &lt;a href="http://www.codeproject.com/KB/cs/AttributeBaseValidation.aspx"&gt;http://www.codeproject.com/KB/cs/AttributeBaseValidation.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:fdc3a8c5-5226-4661-a835-8aba9d304d7c" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;,&lt;a href="http://technorati.com/tags/.NET" rel="tag"&gt;.NET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Reflection" rel="tag"&gt;Reflection&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=128104"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=128104" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/128104.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa L. Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2008/12/22/an-attribute-based-approach-to-business-object-validation.aspx</guid>
            <pubDate>Mon, 22 Dec 2008 12:51:03 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/128104.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2008/12/22/an-attribute-based-approach-to-business-object-validation.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/128104.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/128104.aspx</trackback:ping>
        </item>
        <item>
            <title>DataObjects.NET 4.0 brings new licensing model and features</title>
            <link>http://geekswithblogs.net/malisancube/archive/2008/10/27/dataobjects.net-4.0-brings-new-licensing-model-and-features.aspx</link>
            <description>I looked at the DataObjects.NET (&lt;a href="javascript:void(0);/*1225128902983*/"&gt;http://www.x-tensive.com&lt;/a&gt;) website like i always do, and noticed that they have change their licensing model and their product is actually cheaper and very well broken down into &lt;a href="javascript:void(0);/*1225128923154*/"&gt;internal, personal, small business and enterprise&lt;/a&gt;. After going through the presentations for v3.9, i should say i fell in love with the idea of not having to think about the database side of thing, but to rather concentrate of the business layer and the business rules and interface of the application. &lt;br /&gt;
&lt;br /&gt;
Since the release of v4.0. I wanted comprehensive documentation, examples, benchmarks of DataObjects.NET or some ORM which would not require me to define any database specific details. So you will know that i was also impressed with XPO from Developer Express.&lt;br /&gt;
&lt;br /&gt;
X-tensive.com has now released the new update which contains exactly what i wanted. I still want more examples though, but the example included of a WPF + DO4.0 application was quite interesting. It will be interesting to have as many examples as possible, for example, i would want to know if i can incorporate the WCF to make my application more scalable, how would i effectively do it. My quest is  to reduce development time and use a simple, lightning speed ORM which will shadow the develpment team from the databases, but retain the power of persisting (blindly), log, cache, search and utilise the new stuff in the .NET framework. I should say i was amazed with the benchmarks of &lt;a href="javascript:void(0);/*1225128944706*/"&gt;DO4.0 performance&lt;/a&gt;. I think the future is bright for this ORM.&lt;br /&gt;
&lt;br /&gt;
I realised that a wiki, is being updated regularly on the usage of DO4.0 and a blog (http://tips.x-tensive.com/) has been opened to give tips to developers on good practices in .NET development.&lt;br /&gt;
&lt;br /&gt;
One of my main concerns is support and response to queries. I hope it will improve, maybe it has already since the last time i talked to them.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=126229"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=126229" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/126229.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa Langton Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2008/10/27/dataobjects.net-4.0-brings-new-licensing-model-and-features.aspx</guid>
            <pubDate>Mon, 27 Oct 2008 17:32:10 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/126229.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2008/10/27/dataobjects.net-4.0-brings-new-licensing-model-and-features.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/126229.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/126229.aspx</trackback:ping>
        </item>
        <item>
            <title>Blogging from Cape Town</title>
            <link>http://geekswithblogs.net/malisancube/archive/2008/09/23/blogging-from-cape-town.aspx</link>
            <description>&lt;p&gt;I'm having an interesting experience here in Cape Town and enjoying the VS2008, C# 2008, .NET3.5 ADO.NET 3.5 and WinForms. We are digging deep into the DataClasses and the Entity Framework.  I already have suggestions for Microsoft and will publish them as soon as i get some time. &lt;/p&gt;
&lt;p&gt;I will also now begin to blog in the direction of C# more and more as that is my life now. I'm extremely excited about the way thing are going and can't wait to sit and combine all the concepts that we are doing and pushing them on the blog.&lt;/p&gt;
&lt;p&gt;Wow! I think Cape Town is one of the most beautiful places in the world.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=125387"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=125387" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/malisancube/aggbug/125387.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Malisa Langton Ncube</dc:creator>
            <guid>http://geekswithblogs.net/malisancube/archive/2008/09/23/blogging-from-cape-town.aspx</guid>
            <pubDate>Tue, 23 Sep 2008 14:48:15 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/malisancube/comments/125387.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/malisancube/archive/2008/09/23/blogging-from-cape-town.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/malisancube/comments/commentRss/125387.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/malisancube/services/trackbacks/125387.aspx</trackback:ping>
        </item>
    </channel>
</rss>