<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5878313286923455019</id><updated>2012-01-07T15:42:58.847-05:00</updated><category term='c#'/><category term='CodingGuideline C#'/><category term='DLR'/><category term='Visual Studio'/><category term='Jetfire'/><category term='linq to sql'/><category term='Software Engineering'/><category term='Linq'/><category term='persistence'/><category term='SilverLight'/><category term='Regular Expressions'/><category term='SharePoint'/><category term='WPF/E'/><category term='Web Parts'/><category term='.net'/><category term='Workflow'/><category term='WPF'/><category term='Dynamic Object'/><category term='Visual Studio 2010'/><category term='ASP.net'/><category term='C Sharp'/><title type='text'>your .net design team</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Blogs TrackerRealm</name><uri>http://www.blogger.com/profile/00331907846645255860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>57</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-343533958591934171</id><published>2011-06-07T09:51:00.001-04:00</published><updated>2011-06-07T09:51:20.984-04:00</updated><title type='text'>Intro To .net Rx Extensions</title><content type='html'>&lt;p&gt;Attached is the presentation and the code used in the ODNC presentation on June 6, 2011.&lt;/p&gt;  &lt;p&gt;&lt;a href="ftp://trackerrealm.com/TrWebSite/Blogs/IntroToRX.Jun6.2011.ODNC.SlidesandCode.zip" target="_blank"&gt;Visual Studio Code and presentation.&lt;/a&gt;    &lt;br /&gt;&lt;a href="ftp://trackerrealm.com/TrWebSite/Blogs/RxOverviewODNCJun6.2011.ppt" target="_blank"&gt;Intro To Rx Extensions Presentation&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-343533958591934171?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/343533958591934171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=343533958591934171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/343533958591934171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/343533958591934171'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2011/06/intro-to-net-rx-extensions.html' title='Intro To .net Rx Extensions'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8473140151366219469</id><published>2011-01-24T15:03:00.001-05:00</published><updated>2011-01-24T15:03:51.458-05:00</updated><title type='text'>Ottawa IT Camp 2011 is scheduled</title><content type='html'>&lt;p&gt;I am looking forward to Ottawa IT Camp (previously called Code Camp) 2011 scheduled for Saturday, April 16, 2011.&amp;#160; &lt;/p&gt;  &lt;p&gt;IT Camp is a one-day training event for developers, database administrators and IT people.&lt;/p&gt;  &lt;p&gt;We will be there to talk about some topic in &lt;a href="http://www.jetfire.ca/"&gt;Jetfire&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8473140151366219469?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8473140151366219469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8473140151366219469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8473140151366219469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8473140151366219469'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2011/01/ottawa-it-camp-2011-is-scheduled.html' title='Ottawa IT Camp 2011 is scheduled'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-7684173509574976548</id><published>2010-11-24T17:00:00.001-05:00</published><updated>2010-11-24T17:01:48.802-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Building an Admin Panel using Web Parts Presentation</title><content type='html'>&lt;p&gt;Today I presented this topic at the Ottawa Dot Net Community.&amp;#160; Good turn-out with about 20 people.&amp;#160; This was a one-hour lunch-time presentation.&lt;/p&gt;  &lt;p&gt;The agenda covered:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Web Parts Overview&lt;/li&gt;    &lt;li&gt;Admin Panel mini-spec&lt;/li&gt;    &lt;li&gt;Admin Panel Code Demo&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The overview is a series of slides in the PowerPoint presentation providing a quick summary of Web Parts from Personalization tables to Zones for browsing, editing and catalogs.&lt;/p&gt;  &lt;p&gt;The mini-spec is a one page summary of the key points for the Admin Panel (see slide 14).&lt;/p&gt;  &lt;h2&gt;Let’s Code&lt;/h2&gt;  &lt;p&gt;Finally the last 35 minutes looked at the key design issues and how to solve them in code:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Instantiation vs Reflection&lt;/li&gt;    &lt;li&gt;Only display the active Web Part&lt;/li&gt;    &lt;li&gt;Initializing the Panel&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In designing an Admin Panel, I am adamant that labels on the user interface be totally customizable. This means that the labels not only map to the Web Part properties, such as Title, but also track personalization changes that a customer makes to a Web Part.&amp;#160; &lt;/p&gt;  &lt;p&gt;Instantiation creates objects where the properties have default values. Reflection tries to find the Web Part on the page and use the values saved in the Personalization database.&lt;/p&gt;  &lt;p&gt;When there over three Web Parts on an Admin Page, it is important to hide the Web Parts that are not in use. I call this a “Point, click, Use” interface.&amp;#160; Point the mouse at the link for the web part that you want to use. Click the link. Use the Web Part that appears on the screen.&amp;#160; There should only be one Admin Web Part visible on the page.&lt;/p&gt;  &lt;p&gt;Finally the panel is initialized when we use reflection to create Web Parts. This means that the first time that the page is displayed, all Web Parts are automatically added to the page.&amp;#160; We are ready to customize them.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://trackerRealm.com/Blogs/2010/AdminPanel/ODNC Building Admin Panel.zip"&gt;Slides and sample Demo Admin Panel Web Part&lt;/a&gt; code are included.&lt;/p&gt;  &lt;p&gt;Contents include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;PowerPoint slides&lt;/li&gt;    &lt;li&gt;DemoAdminPanelWebPart.cs&lt;/li&gt;    &lt;li&gt;L.cs (a collection of useful statics for manipulating Web Parts)&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-7684173509574976548?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/7684173509574976548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=7684173509574976548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7684173509574976548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7684173509574976548'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/11/building-admin-panel-using-web-parts.html' title='Building an Admin Panel using Web Parts Presentation'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-4335190397900662425</id><published>2010-11-23T08:55:00.001-05:00</published><updated>2010-12-04T17:14:05.881-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Jetfire Version 1.3</title><content type='html'>&lt;p&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://www.jetfire.ca/images/poweredbyjetfire.png" width="106" height="44" /&gt; This new version of the &lt;a href="http://www.jetfire.ca/default.aspx"&gt;dynamic programming language Jetfire&lt;/a&gt; (available for download on &lt;a href="http://jetfire.codeplex.com/"&gt;Codeplex&lt;/a&gt;) provides a number of new features and improvements.&amp;#160; To provide these new features and improvements a new expression parser has been written to employ &lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;Linq expression trees&lt;/a&gt;.&amp;#160;&amp;#160; Version 1.3 contains both the new expression parser and the original expression interpreter.&amp;#160; This allows the original expression interpreter to be used by simply changing a setting should any problems be encountered.&lt;/p&gt;  &lt;p&gt;Version 1.3.x will provide the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Improved Performance&lt;/strong&gt;:&amp;#160; &lt;br /&gt;The expectation over the next few releases is that performance of the Jetfire code will be close to that of C#.&amp;#160;&amp;#160; Jetfire version 1.3.0 is already 2x faster than V1.2.x.&amp;#160; Benchmarks on parts of the expression parser that are still in lab indicate performance parity between C# and Jetfire.&amp;#160; This is an ambitious, perhaps even outrageous,&amp;#160; goal for a dynamic language.&amp;#160; We do have a high degree of confidence that we can meet this goal.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Duck Typing&lt;/strong&gt;:      &lt;br /&gt;Version 1.3.0 now supports &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;‘duck’ typing&lt;/a&gt;.&amp;#160;&amp;#160; This provides a very simple alternative to Interfaces.&amp;#160;&amp;#160; Jetfire ‘duck’ typing will be enhanced in coming releases with a simple, yet effective construct that will aid in compile time checking and&amp;#160; &lt;a href="http://en.wikipedia.org/wiki/Autocompletion"&gt;auto complete&lt;/a&gt; (&lt;a href="http://en.wikipedia.org/wiki/IntelliSense"&gt;intellisense&lt;/a&gt;) for IDEs such as Visual Studio.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Dynamic operators&lt;/strong&gt;:      &lt;br /&gt;Operators can now be dynamic.&amp;#160; For example the following is valid Jetfire code.      &lt;br /&gt;&lt;em&gt;string s = Add(“my”, “string”);       &lt;br /&gt;int i = Add(1, 6);        &lt;br /&gt;…        &lt;br /&gt;public object Add(object a, object b)        &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return a+b;        &lt;br /&gt;}&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ReadOnly objects&lt;/strong&gt;:      &lt;br /&gt;Now complete objects can be made ‘read only’ which compliments the existing ‘read only’ property functionality using roles.&amp;#160;&amp;#160; With release 1.3.0 the first use of a ‘read only’ object is ‘Empty’; however with future updates it will possible for objects to be dynamically ‘read only’ based on roles.&amp;#160;&amp;#160; This will allow an object to be ‘read write’ by, for example the object owner, some users can only read the object and while other users have no access at all to the object.&amp;#160;&amp;#160; When a read only object is used an exception occurs if an attempt is made to write a ‘read only’ object.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Improved Void Safety&lt;/strong&gt;:&amp;#160; &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Void_safety"&gt;Void safety&lt;/a&gt; has made a step forward as all objects are automatically assigned the ‘read only’ &lt;a href="http://wiki.jetfire.ca/Empty%20Object.ashx"&gt;‘Empty’ object&lt;/a&gt; instead of null.&amp;#160; It is still possible to assign objects to null (and still get the dreaded ‘null object exception’), but the ‘Empty’ object greatly enhances void safety.&amp;#160; ‘Empty’ objects can be created programmatically via Jetfire software, otherwise they are automatically created.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Easy Reflection&lt;/strong&gt;:      &lt;br /&gt;The plan is to add a very simple mechanism to support calling methods (very simple &lt;a href="http://en.wikipedia.org/wiki/Delegate_(.NET)"&gt;delegate&lt;/a&gt; mechanism) and creating new workflows based on string variables.&amp;#160; For example:      &lt;br /&gt;&lt;em&gt;string s = “MyMethod”;       &lt;br /&gt;Call s();        &lt;br /&gt;&lt;/em&gt;Or      &lt;br /&gt;&lt;em&gt;string s = “MyClass”;       &lt;br /&gt;MyClass myClass = new s();&lt;/em&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-4335190397900662425?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/4335190397900662425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=4335190397900662425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4335190397900662425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4335190397900662425'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/11/jetfire-version-13.html' title='Jetfire Version 1.3'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8511465589391605251</id><published>2010-10-25T14:25:00.005-04:00</published><updated>2010-10-25T15:20:47.491-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Auto-generate Documentation for Web Parts</title><content type='html'>&lt;p&gt;As a designer, I constantly struggle with the time required for designing great software programs and writing user documentation that helps people understand how to use the program.  [Some people argue that if it’s a great program, it doesn’t need documentation, but I know that even the brightest users often need a push in the right direction for how to get the most out of the product.]&lt;/p&gt;  &lt;p&gt;I am particularly interested in auto-generating documentation for Web Part Properties.  The &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/10/design-for-web-part-based-admin-panel.html" target="_blank"&gt;CMS Admin Panel&lt;/a&gt; got me thinking about this problem.  The Admin Panel needed an Admin Help Index – a list of the Web Parts in the Admin Panel, who can access them and a short summary of what they do.  Since this information is readily available in the Web Part itself, I decided to auto-generate this documentation.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Auto-generating the Admin Help Index&lt;/h3&gt;  &lt;p&gt;I auto-generated the Admin Help Index in a Web Part using the following algorithm:&lt;/p&gt;  &lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Order the Web Parts in alphabetical order&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[] webParts = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[mgr.WebParts.Count];&lt;br /&gt;mgr.WebParts.CopyTo(webParts, 0);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IEnumerable&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt; parts = webParts.OrderBy(x =&amp;gt; x.DisplayTitle);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wp &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; parts)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IAdminRole&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; admin = wp &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IAdminRole&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (admin == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;continue&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddBreak(2, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddLabel(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Title: "&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddStyle2H3(wp.DisplayTitle), &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Unit&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddBreak(1, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (admin.AdminRole != &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddLabel(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"* Roles required to access: "&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + admin.AdminRole, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Unit&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddBreak(1, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddLiteral(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"* Description: "&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + wp.Description, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Code Snippet 1: Generate an Admin Help Index&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Some notes about the algorithm used in Code Snippet 1:&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Use the WebPartManager to find all Web Parts on the Page. The Admin Panel is on a page that contains all Web Parts indexed from the Admin Panel.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Using LINQ, order the Web Parts alphabetically. In this case, I used the DisplayTitle property as the key.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;The ‘&lt;span style="list-style-type: disc;"&gt;&lt;span style="color: rgb(43, 145, 175);font-family:Consolas;" &gt;IAdminRole&lt;/span&gt;&lt;/span&gt;’ interface is used in Web Parts to identify the none, one or more roles that can access the (admin) Web Part.  This comes in handy in filtering out the Admin Web Parts on the page.  [There are other Web Parts on the page used for image header and navigation menu.]&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Format the output as shown below.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr /&gt;&lt;span style="font-family:Arial;"&gt;&lt;span&gt;Title: &lt;span&gt;&lt;b&gt;&lt;span style="font-size:14.4pt;"&gt;Assign Roles to CMS User&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span id="ctl00_ctl00_WebPartManager1_wp1738354389_ctl04"&gt;* Roles required to access: WebMaster,Admin&lt;/span&gt;&lt;br /&gt;* Description: TrackerRealm Assign Users Web Part assigns roles to a user.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;&lt;/span&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;The Admin Help Index uses Web Part Properties: DisplayTitle, Description and the IAdminRole interface to create a help index.&lt;/span&gt;&lt;br /&gt;&lt;h3&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Auto-generating Documentation for Web Part Properties&lt;/span&gt;&lt;/h3&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Auto-generating Documentation for Web Part properties needs to use reflection to find the properties for the Web Part (because we only have the base class).  I decided to write a Web Part for auto-generating documentation for Web Part Properties.  This allows me to dynamically add the Web Part to a page and change the default property values.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Here are the requirements for the AutoGenWebPart:&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Accept input from the query string for the type of Web Part requested.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Generate a header and list of properties showing each display name, description and default value, if used.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Output the documentation in html for display on a web page, plain text, or wiki, for inclusion in a wiki.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Query String input&lt;/h4&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;span&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets and Sets the format that the documentation is output: wiki, text, html&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Category&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Display"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;), &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Browsable&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;), &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Personalizable&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PersonalizationScope&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Shared), &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;&lt;br /&gt;WebDisplayName&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Output Type"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;), &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;DisplayName&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Output Type"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Description&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Describes the format that the documentation is output: wiki, text, html."&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)]&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OutputType&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; OutputType&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.op;  }&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.op = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;  }&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Code Snippet 2: Sample Property for a Web Part Property&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;The property in Code Snippet 2 shows the Display Name and Description used in the documentation.  This is meaningful to the user because the Web Part editor displays the Display Name for each Property.&lt;/span&gt;&lt;br /&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wpType = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Context.Request.QueryString.Get(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"name"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (wpType == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.OutputText(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"No request received"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; type = System.Web.Compilation.&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;BuildManager&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.GetType(wpType, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (type == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.OutputText(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Cannot find "&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + wpType);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wp = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Activator&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.CreateInstance(type) &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (wp == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.OutputText(wpType + &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;" is not a Web Part"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Code Snippet 3: Create the Web Part&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;The first step in the Web Part is getting the requested (type) name for the Web Part from the query string. If there is no parameter for ‘name’, then the user receives no output &lt;span style="font-family:Consolas;"&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(163, 21, 21);"&gt;"No request received"&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;p&gt;&lt;/p&gt;&lt;p&gt;With a text version of the type present, we can use reflection to get the Class and then create an instance of the class. If the type is not a Web Part class, then the user receives no output &lt;span style="white-space: pre;font-family:Consolas;" &gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(163, 21, 21);"&gt;"Cannot find "&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre;font-family:Consolas;" &gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt; + wpType).&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;h4&gt;&lt;span style="font-family:Consolas;"&gt;Auto-generate the Documentation &lt;/span&gt;&lt;/h4&gt;&lt;h4&gt;&lt;/h4&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;sb.AppendFormat&lt;/span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"{0}{1}{2}{3}"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.h4s, wp.Title, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.h4e, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.br);&lt;br /&gt;sb.AppendFormat(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"{0}Description{1}: {2}{3}"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.bs, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.be, wp.Description, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.br);&lt;br /&gt;sb.AppendFormat(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"{0}Properties{1}{2}"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.h5s, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.h5e, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty);&lt;br /&gt;sb.AppendFormat(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Properties are listed alphabetically{0}"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.br);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptorCollection&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; properties = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;TypeDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.GetProperties(wp);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[] props = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptor&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[properties.Count];&lt;br /&gt;properties.CopyTo(props, 0);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IEnumerable&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt; pds = props.Where&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;(x =&amp;gt; x.Category == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Display"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt; .OrderBy(x =&amp;gt; x.DisplayName);&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Sets an PropertyDescriptor to the specific property.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; p &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pds)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;switch&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (p.Name)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;case&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Title"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;case&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Description"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;continue&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;}&lt;br /&gt;sb.AppendFormat(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"{0} {1}{2}{3}: {4}{5}"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.star, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.bs, p.DisplayName, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.be, p.Description, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.br);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; o = p.GetValue(wp);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (o == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;continue&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value = o.ToString();&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (value != &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty)&lt;br /&gt;sb.AppendFormat(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"{0}{1} Default Value: {2}{3}"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.tab, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.star, value, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Consolas;" &gt;.br);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Code Snippet 4: Auto-Generate the Property list for a Web Part&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Code Snippet 4 shows the steps involved in auto-generating the documentation for the Web Part.  It looks unnecessarily complicated with the formatting options defined by the instance variables.  Let’s dissect the first statement: &lt;/span&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;&lt;span style="white-space: pre;font-family:Consolas;" &gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;sb.AppendFormat&lt;/span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre;font-family:Consolas;" &gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(163, 21, 21);"&gt;"{0}{1}{2}{3}"&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;.h4s, wp.Title, &lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;.h4e, &lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre;font-family:Consolas;" &gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;.br);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;I wanted to dress up the title, so I included text formatting in the formatter.&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;wp.Title is the Title of the Web Part&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;this.h4s is the starting format for the title&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;this.h4e is the ending format for the title&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;this.br is the break between lines&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Each variable was initialized with the wiki syntax.  I then created a method for initializing the output of html and plain text.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;The key statement in the mix is getting the properties:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(43, 145, 175);"&gt;PropertyDescriptorCollection&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt; properties = &lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="white-space: pre; color: rgb(43, 145, 175);"&gt;TypeDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre; color: rgb(0, 0, 0);"&gt;.GetProperties(wp);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;This statement uses reflection to get the properties of the Web Part.&lt;/span&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IEnumerable&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt; pds = props.Where&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyDescriptor&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;(x =&amp;gt; x.Category == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Display"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;  .OrderBy(x =&amp;gt; x.DisplayName);&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Copy the properties into an array and then using System.Linq extensions, we find the Display Category properties and order them by DisplayName.&lt;/span&gt;&lt;h4&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Display the Output&lt;/span&gt;&lt;/h4&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; OutputText(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; text)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.outputType == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OutputType&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Html)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  System.Text.&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;StringBuilder&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sb = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Text.&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;StringBuilder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; styleSheet = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Format(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"http://{0}{1}/app_themes/{2}/stylesheet.css"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,&lt;br /&gt;  context.Request.Url.Authority, context.Request.ApplicationPath, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"default"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;sb.AppendFormat(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;@"&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;link href=""{0}"" type=""text/css""&lt;br /&gt;  rel=""Stylesheet""/&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, styleSheet);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  sb.Append(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Write the content to the Web Page&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  context.Response.ContentType = &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);font-family:Consolas;" &gt;"text/HTML"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;context.Response.Write(sb.ToString());&lt;br /&gt;context.Response.End();&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Display the Documentation as a text file (applies to txt and wiki options)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Context.Response.ContentType = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"text/plain"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Context.Response.Write(text);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Context.Response.End();&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Code Snippet 5: Output the text&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;The wiki and plain text format are output by writing the text to the browser.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Writing html is essentially the same, but is complicated because I like seeing the documentation with a good looking style sheet, in this case the style sheet from the default theme.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;The following table shows a partial sample output of documenatation auto-generated for the CMS Admin Panel Web Part.&lt;/span&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The following information is a brief description and list of properties for a Web Part developed by TrackerRealm. It is meant as a help summary.&lt;br /&gt;&lt;h2&gt;&lt;span style="font-family:Arial;"&gt;CMS Admin Panel&lt;/span&gt;&lt;/h2&gt;&lt;br /&gt;&lt;b&gt;Description&lt;/b&gt;: TrackerRealm CMS Admin Panel Web Part presents the administrative options for the site. The Correct Web Part is displayed for the selected action.&lt;br /&gt;&lt;h3&gt;Properties&lt;/h3&gt;&lt;br /&gt;Properties are listed alphabetically&lt;br /&gt;* &lt;b&gt;Admin Role&lt;/b&gt;: The roles allowed to access this Web Part.&lt;br /&gt;* Default Value: Admin&lt;br /&gt;* &lt;b&gt;Allow login to Jetfire?&lt;/b&gt;: Check if the login to Jetfire is allowed for users&lt;br /&gt;* Default Value: False&lt;br /&gt;* &lt;b&gt;Back Color&lt;/b&gt;: Back Color for the Web Part.&lt;br /&gt;* Default Value: Color [Empty]&lt;br /&gt;* &lt;b&gt;Devices&lt;/b&gt;: Devices that are allowed to see this WebPart: All, Normal, Mobile.&lt;br /&gt;* Default Value: AllDevices&lt;br /&gt;&lt;br /&gt;&amp;lt;--snip--&amp;gt;&lt;/span&gt;&lt;hr /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8511465589391605251?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8511465589391605251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8511465589391605251' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8511465589391605251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8511465589391605251'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/10/auto-generate-documentation-for-web.html' title='Auto-generate Documentation for Web Parts'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-1669453644317058574</id><published>2010-10-22T14:56:00.004-04:00</published><updated>2010-11-18T10:21:42.695-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Building a News Scroller with Jetfire</title><content type='html'>&lt;p&gt;Making an impact on web pages is about keeping the information concise and attractive.  Most home pages use a scroller for news and/or events.&lt;/p&gt;  &lt;p&gt;The Jetfire News Scroller makes it easy to add news to your home page.  It includes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Jetfire code&lt;!--EndFragment--&gt;&lt;/li&gt;    &lt;li&gt;A Web Part with a Rich Text Editor for creating a news item&lt;!--EndFragment--&gt;&lt;/li&gt;    &lt;li&gt;A Web Part with a scroller for displaying news items&lt;/li&gt;    &lt;li&gt;jquery javascript for implementing the scroller&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Jetfire code&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://www.jetfire.ca"&gt;Jetfire Persistent Scripting Language&lt;/a&gt; is an open source, object oriented, scripting language designed to make persistent programs, sometimes called workflows, very easy to write and maintain.  The News Item displayed in the scroller is a simple program, which consists of:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Some properties that are displayed on the web page&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Title of the News Item&lt;/li&gt;      &lt;li&gt;The body of the News Item (photos and text)&lt;/li&gt;      &lt;li&gt;An expiry date&lt;/li&gt;      &lt;li&gt;Who created the news item&lt;/li&gt;      &lt;li&gt;When the news item was created&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;A method for identifying that the News Item is Current&lt;/li&gt;    &lt;li&gt;States for the news item&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Active: Display the news item&lt;/li&gt;      &lt;li&gt;Inactive: Don’t display the news item&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Consolas;" &gt;namespace JetfireApps&lt;br /&gt;{&lt;br /&gt;// This workflow creates News Items with an expiry date.&lt;br /&gt;// Use 'IsCurrent' to check the Expiry Date and identify if the News Item is current.&lt;br /&gt;// state Active means that the News Item is current.&lt;br /&gt;public workflow NewsItem&lt;br /&gt;{&lt;br /&gt;// Add workflow constructor&lt;br /&gt;public NewsItem()&lt;br /&gt;{&lt;br /&gt;Tags = new List();&lt;br /&gt;enterstate Start();&lt;br /&gt;Created_Date = DateTime.Now;&lt;br /&gt;Created_By = User.Login.Name;&lt;br /&gt;Expiry_Date = DateTime.Today.AddYears(1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Add states to the workflow&lt;br /&gt;public Start()   { }&lt;br /&gt;public Active() { }&lt;br /&gt;public Inactive() { }&lt;br /&gt;&lt;br /&gt;// Add Properties&lt;br /&gt;// Use Subject as News Title&lt;br /&gt;// Use ToolTip as News Description&lt;br /&gt;// Add Expiry Date&lt;br /&gt;public bool Never_Expires&lt;br /&gt;{&lt;br /&gt;get;&lt;br /&gt;set;&lt;br /&gt;}&lt;br /&gt;public DateTime Created_Date&lt;br /&gt;{&lt;br /&gt;get;&lt;br /&gt;private set;&lt;br /&gt;}&lt;br /&gt;public plainString Created_By&lt;br /&gt;{&lt;br /&gt;get;&lt;br /&gt;private set;&lt;br /&gt;}&lt;br /&gt;public DateTime LastUpdated_Date&lt;br /&gt;{&lt;br /&gt;get;&lt;br /&gt;private set;&lt;br /&gt;}&lt;br /&gt;public plainString LastUpdated_By&lt;br /&gt;{&lt;br /&gt;get;&lt;br /&gt;private set;&lt;br /&gt;}&lt;br /&gt;public DateTime Expiry_Date&lt;br /&gt;{&lt;br /&gt;get;&lt;br /&gt;set;&lt;br /&gt;}&lt;br /&gt;public List Tags&lt;br /&gt;{&lt;br /&gt;get;&lt;br /&gt;private set;&lt;br /&gt;}&lt;br /&gt;public bool IsCurrent&lt;br /&gt;{&lt;br /&gt;get&lt;br /&gt;{&lt;br /&gt; if (Never_Expires)&lt;br /&gt; {&lt;br /&gt;  return true;&lt;br /&gt; }&lt;br /&gt; if (DateTime.Now.Preceeds(Expiry_Date))&lt;br /&gt; {&lt;br /&gt;  return true;&lt;br /&gt; }&lt;br /&gt; // This news item is now expired&lt;br /&gt; enterstate Inactive();&lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Add Command Methods&lt;br /&gt;public void FinishEdit() : states(Start,Active)&lt;br /&gt;{&lt;br /&gt;if (Subject == "")&lt;br /&gt;{&lt;br /&gt; throw exception("Enter Title");&lt;br /&gt;}&lt;br /&gt;if (ToolTip == "")&lt;br /&gt;{&lt;br /&gt; throw exception("Enter Description");&lt;br /&gt;}&lt;br /&gt;LastUpdated_Date = DateTime.Now;&lt;br /&gt;LastUpdated_By = User.Login.Name;&lt;br /&gt;enterstate Active();&lt;br /&gt;}&lt;br /&gt;public void Set_Inactive() : states(Active)&lt;br /&gt;{&lt;br /&gt;enterstate Inactive();&lt;br /&gt;}&lt;br /&gt;public void Set_Active() : states(Inactive)&lt;br /&gt;{&lt;br /&gt;enterstate Active();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h3&gt;Rich Text Editor in a Web Part&lt;/h3&gt;&lt;p&gt;Someone has to create the news that is displayed on the website.  Figure 1 shows a portion of a Jetfire page that we use to create our news. There are two Web Parts displayed on the figure.  &lt;/p&gt;&lt;ul&gt;&lt;li&gt;The Web Part on the left is a Workflows Navigation Web Part that is configured to display a list of all News Items.&lt;/li&gt;  &lt;li&gt;The Web Part on the right is the News Item Editor. It contains:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;State of the News item&lt;/li&gt;    &lt;li&gt;Some commands that the user can to manage the news item&lt;/li&gt;    &lt;li&gt;The Properties of the News Item: Title, Never Expires, Expiry Date and Body&lt;/li&gt;  &lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;The Body of the News Item is a Rich Text Editor that allows the user to input rich text, images and links.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Building-a-News-Scroller-with-Jetfire_A7E2/NewsScroller-Editor.png"&gt;&lt;img style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="NewsScroller-Editor" alt="NewsScroller-Editor" src="http://www.trackerrealm.com/blogimagesmore/Building-a-News-Scroller-with-Jetfire_A7E2/NewsScroller-Editor_thumb.png" width="578" border="0" height="420" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Figure 1: News Editor in web page&lt;/span&gt;&lt;/p&gt;&lt;h3&gt;News Scroller Web Part&lt;/h3&gt;&lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Building-a-News-Scroller-with-Jetfire_A7E2/NewsScroller.png"&gt;&lt;img style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="NewsScroller" alt="NewsScroller" src="http://www.trackerrealm.com/blogimagesmore/Building-a-News-Scroller-with-Jetfire_A7E2/NewsScroller_thumb.png" width="577" border="0" height="283" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Figure 2: News Scroller in web page&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Figure 3: A subset of properties used to configure the News Scroller&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt; (below)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Building-a-News-Scroller-with-Jetfire_A7E2/NewsScroller-EditProperties.png"&gt;&lt;img style="background-image: none; border: 0px none; margin: 0px 28px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; padding-top: 0px;" title="NewsScroller-EditProperties" alt="NewsScroller-EditProperties" src="http://www.trackerrealm.com/blogimagesmore/Building-a-News-Scroller-with-Jetfire_A7E2/NewsScroller-EditProperties_thumb.png" width="265" align="left" border="0" height="445" /&gt;&lt;/a&gt;Figure 2 shows the News Scroller in the home page of &lt;a href="http://www.jetfire.ca/"&gt;http://www.jetfire.ca&lt;/a&gt;.   The Web Part is configured to display a new item every 400 milli-seconds.  The user may also choose to manually select a News Item.&lt;/p&gt;&lt;p&gt;The News Item program can be configured in different ways by a Web Master for display on the web page.  Options include:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Display the Active News Items&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Let the news item editor manage the states of the News Items.  When a News Item has out-lived its time, the editor sets the state to Inactive&lt;/li&gt;  &lt;/ul&gt;  &lt;li&gt;Display News Items that have not expired&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Let the news item editor establish an expiry date for each news item. Some companies expect news items to be displayed at least 2 weeks.  Then the news item is delisted.  This option tracks expiry for the editor.&lt;/li&gt;  &lt;/ul&gt;&lt;/ol&gt;&lt;p&gt;Figure 3 shows a subset of the edit properties for the News Scroller.  The Web Master has a number of options that describe how the News Scroller will operate.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Select what News Items are displayed using the first propery: Filter.  By providing a list of name/value pairs, the software converts this into a filter used to get the list of News Items.&lt;/li&gt;  &lt;li&gt;Display the header option? If Checked, then the “Created on …..” is displayed.  The Web Master can create the header format by editing the Header Property. The format is “Created on {0} by {1} to {2}” where {0} is the value of the Created by Property, {1} is the value of the Created Date Property and {2} is the value of the Workspace where the News Item is stored.&lt;/li&gt;  &lt;li&gt;Auto-rotate may be enabled/disabled.&lt;/li&gt;  &lt;li&gt;The Rotation interval may be set.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;jquery javascript library&lt;/h3&gt;&lt;p&gt;&lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt; is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. We use this as our AJAX JavaScript library.  jquery has an active community, who are constantly submitting new programs.  One such program is &lt;em&gt;Featured Content Glider&lt;/em&gt;:  by &lt;a href="http://www.dynamicdrive.com/"&gt;http://www.dynamicdrive.com&lt;/a&gt;.   It includes the javascript and the css stylesheet used in the news scroller.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-1669453644317058574?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/1669453644317058574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=1669453644317058574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1669453644317058574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1669453644317058574'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/10/building-news-scroller-with-jetfire.html' title='Building a News Scroller with Jetfire'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2650696581295665171</id><published>2010-10-22T11:22:00.002-04:00</published><updated>2010-10-22T15:38:44.119-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Change Session State Programmatically</title><content type='html'>&lt;p&gt;Customers using Jetfire Workflows rely on websites with good connectivity to stay connected to their business and keep their business processes up-to-date.  Recently, our ISP moved their Data Center to be better served by a higher speed internet connection.  Web pages are definitely served faster, but I also noticed busy intervals during the day leading to page rendering delays and often dropped logins for customers.  The dropped logins require users to re-login – a nuisance when you are busy.&lt;/p&gt;  &lt;p&gt;Session State in the web.config file is set up as ‘InProc’, meaning that the Session State is stored in memory.  By changing Session State to ‘SqlServer’, the goal was to avoid unnecessary re-logins.&lt;/p&gt;  &lt;p&gt;In a hosted environment, this procedure is:  &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Run the sql script for the ASPState database on the local server&lt;/li&gt;    &lt;li&gt;Change the Session State parameter in web.config to ‘SqlServer’ &lt;/li&gt;    &lt;li&gt;Set the parameters for the SqlServer Session State&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In an ISP environment, step 1 is changed to create the database and upload the database schema.&lt;/p&gt;  &lt;p&gt;For our lazy deployment person (that’s me), even this simple procedure was too complicated.  I needed a one-click procedure to &lt;a href="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionState-Memory.png"&gt;&lt;img style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; float: right; padding-top: 0px;" title="SessionState-Memory" alt="SessionState-Memory" src="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionState-Memory_thumb.png" width="389" align="right" border="0" height="185" /&gt;&lt;/a&gt;manage the transition automatically and minimize the amount of effort required to convert each site.&lt;/p&gt;  &lt;p&gt;These are the design steps used to add the session state tables to an existing database and then create a Web Control to change the session state.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create the ASPState tables in my local database&lt;/li&gt;    &lt;li&gt;Create a script for the ASPState tables&lt;/li&gt;    &lt;li&gt;Put a C# code wrapper around the ASPState sql script&lt;/li&gt;    &lt;li&gt;Create a Web Control that changes Session State with one-click&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The figure on the right shows the desired end result – a web control that changes Session State from memory storage to database storage and simple enough that the customer administrator can do it.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;ASPState Tables&lt;/h3&gt;  &lt;p&gt;The .NET Framework includes an install database and tables script for ASP State.  Since we are adding the ASPState tables to an existing database, we need to create an sql script that only addresses the tables (and stored procedures).&lt;/p&gt;  &lt;p&gt;This involves installing the ASPState tables in my development system.  The sql script, InstallSqlState.sql, to do this is found in one of the following folders; &lt;code&gt;&lt;span style="color:#333333;"&gt;&lt;em&gt;system drive&lt;/em&gt;\ Windows\ Microsoft.NET\ Framework\&lt;em&gt;version&lt;/em&gt;\.  &lt;/span&gt;&lt;/code&gt;&lt;/p&gt;  &lt;h3&gt;SQL Script for ASPState Tables&lt;/h3&gt;  &lt;p&gt;Once the ASPState database and tables are created, generate the script for the ASPState tables.  I used the Database Publishing Wizard found in codeplex project: &lt;a href="http://sqlhost.codeplex.com/"&gt;http://sqlhost.codeplex.com&lt;/a&gt;.  Just follow the instructions.&lt;/p&gt;  &lt;h3&gt;C# code wrapper about sql script&lt;/h3&gt;  &lt;p&gt;The sql script is not a slam dunk at this point. There are a few gotchas that need to be addressed.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The sql script does not contain the name of the customer’s database. When ISP hosting is used, it is highly likely that every database that the ASPState tables are added to has a different name.  Therefore, a name, such as ‘&lt;span&gt;&lt;span style="font-family:Consolas;color:#a31515;"&gt;DatabaseNamePlaceHolder&lt;span style="font-family:Trebuchet MS;color:#000000;"&gt;’ is embedded in the file in multiple places. (there were over 80 places where this occurs)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;span&gt;Delete the GO statements. Do a replace all ‘GO’ strings with ‘’ (an empty string).&lt;/span&gt;&lt;/li&gt;    &lt;li&gt;strings in the file, e.g. “2” need to be converted to “”2””. [there was only one instance to change.]&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionStateSqlScript.png"&gt;&lt;img style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="SessionStateSqlScript" alt="SessionStateSqlScript" src="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionStateSqlScript_thumb.png" width="622" border="0" height="264" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:#0000ff;"&gt;Code Snippet 1: SQL Script for ASPState tables&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;The above code snippet shows a portion of the SQL script for installing ASPState tables.&lt;/p&gt;  &lt;p&gt;Note: The sql script is over 1100 lines of code, which is why it is not included in its entirety.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionStateCreateTables.png"&gt;&lt;img style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="SessionStateCreateTables" alt="SessionStateCreateTables" src="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionStateCreateTables_thumb.png" width="599" border="0" height="148" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:#0000ff;"&gt;Code Snippet 2: Create the ASPState Tables&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;The above code snippet creates the tables for the ASPState tables.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Get the Connection String where the tables will be added.&lt;/li&gt;    &lt;li&gt;Instantiate an SqlConnection object. This is used to get the name of the customer’s Database.&lt;/li&gt;    &lt;li&gt;Get the sql script and replace ‘&lt;span&gt;&lt;span style="font-family:Consolas;color:#a31515;"&gt;DatabaseNamePlaceHolder&lt;span style="font-family:Trebuchet MS;color:#000000;"&gt;’ with the name of the customer’s Database.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;span&gt;Execute the modified script on the database.&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;span&gt;The end result is tables: ASPStateTempApplications and ASPStateTempSessions, along with all Stored Procedures are installed in the target database.&lt;/span&gt;&lt;/p&gt;  &lt;h3&gt;Web Control that changes Session State with one-click&lt;/h3&gt;  &lt;p&gt;This section addresses how to change the mode for Session State programmatically.  (The user interface code is straight-forward.)  The Session State is located in the web.config file at the root of the website. It is retrieved using the code found in Code Snippet 3.&lt;/p&gt;  &lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;.config = System.Web.Configuration.&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;WebConfigurationManager&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;.OpenWebConfiguration(&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a31515;"&gt;"~/"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;SystemWebSectionGroup&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; webGroup = &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;.config.GetSectionGroup(&lt;/span&gt;&lt;span&gt;&lt;span style="color:#a31515;"&gt;"system.web"&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;) &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;SystemWebSectionGroup&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;.sessionState = webGroup.SessionState;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style="color:#0000ff;"&gt;Code Snippet 3: Get the Session State from web.config&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The ‘ChangeMode’ method, shown in Code Snippet 4, is called from the link click event of the Web Control.  Key points include:&lt;br /&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Only SQLServer and InProc modes are supported&lt;/li&gt;  &lt;li&gt;The session State object is updated for the selected mode&lt;/li&gt;  &lt;li&gt;A message is printed to the user providing a positive indication of what has changed&lt;/li&gt;  &lt;li&gt;The change is saved in the web.config file.&lt;/li&gt;  &lt;li&gt;Text displayed on the Web Control is updated.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionState-ChangeModeCode.png"&gt;&lt;img style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="SessionState-ChangeModeCode" alt="SessionState-ChangeModeCode" src="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionState-ChangeModeCode_thumb.png" width="677" border="0" height="478" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#0000ff;"&gt;Code Snippet 4: Change the Mode of the Session State&lt;/span&gt;&lt;/p&gt;&lt;p&gt;There is a lot of flexibility in the SQLServer mode for Session State.  Read the MSDN help closely to ensure that you engineer the correct operation for your application.&lt;/p&gt;&lt;p&gt;When the customer Administrator converts the storage of Session State from memory, ‘InProc’ to database, ‘SQLServer’, all users need to re-login because when the web.config is changed for this procedure and of course, because the Session State for each user is now null.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionState-Database.png"&gt;&lt;img style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="SessionState-Database" alt="SessionState-Database" src="http://www.trackerrealm.com/blogimagesmore/Change-Session-State-Programmatically_7DAD/SessionState-Database_thumb.png" width="367" border="0" height="204" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;h3&gt;Object Serialization Gotchas&lt;/h3&gt;&lt;p&gt;Further web testing showed that my work was not finished.  There was one object that was stored correctly when the Session State Mode was ‘InProc’.  However, it was &lt;em&gt;real clear&lt;/em&gt; that the object needed to be serialized to the database when the Session State was changed to ‘SQLServer’.  Whereas, ‘InProc’ stores a reference to the object in the Session memory, ‘SQLServer’ serializes the complete object to the database for each Session.&lt;/p&gt;&lt;p&gt;This required some re-work of the class in question and the code that used the object.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2650696581295665171?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2650696581295665171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2650696581295665171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2650696581295665171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2650696581295665171'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/10/change-session-state-programmatically.html' title='Change Session State Programmatically'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-7826213602738540826</id><published>2010-10-21T18:04:00.002-04:00</published><updated>2010-10-22T08:53:46.525-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Design for a Web Part-based Admin Panel</title><content type='html'>&lt;p&gt;Last month, I outlined the specifications for a Web Part-based Admin Panel. This article reviews the code involved in building the Admin Panel.  The code in this article relies to a limited degree on class libraries, which are not described in detail.  If you are interested in more information about anything in the article, just provide a comment on the blog and answers will appear.&lt;/p&gt;  &lt;p&gt;The Admin Panel is a Web Part. This allows the designer to include personalizable properties, which allow for customization of the Web Part.  Properties include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;AdminRoles: a comma-delimited list of Roles that are allowed access to admin level functions included in the Web Part.  The default Role is “&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);font-family:Consolas;" &gt;Admin&lt;/span&gt;&lt;/span&gt;”. &lt;/li&gt;    &lt;li&gt;LinkCssClass: a css class used to style the links.  The default is “&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);font-family:Consolas;" &gt;hyperlinkV&lt;/span&gt;&lt;/span&gt;”. &lt;/li&gt;    &lt;li&gt;MouseOverCssClass: a css class used to style the links when the user hovers over a link.  The default is “&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);font-family:Consolas;" &gt;hyperlinkVMouseOver&lt;/span&gt;&lt;/span&gt;”. &lt;/li&gt;    &lt;li&gt;TargetZone: the Web Part Zone where Web Parts are created. The default is “&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);font-family:Consolas;" &gt;Row1Column2&lt;/span&gt;&lt;/span&gt;”. &lt;/li&gt;    &lt;li&gt;NavLinksFile: an xml file that contains navigation information for the site to implement the ‘My Links” feature*. The default is the path to the NavLinksFile used in the site. &lt;/li&gt;    &lt;li&gt;MenuName: the name of the menu to display to the user from the NavLinksFile to implement the “My Links” feature.  The default menu name is “&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);font-family:Consolas;" &gt;My Links&lt;/span&gt;&lt;/span&gt;”. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;* The “My Links” feature was added after the specification was finished. A customer said “Wouldn’t it be nice if….” and My Links was born. &lt;/p&gt;  &lt;p&gt;Since properties are standard items for a Web Part, the code is not included for the properties.&lt;/p&gt;  &lt;h3&gt;The Admin Panel and the Web Page&lt;/h3&gt;  &lt;p&gt;The Admin Panel is added to a web page.  When the page is displayed, it displays the CMS Admin Panel shown in the figure below.  Once the user is logged in, the Admin Panel Web Part can be edited to set the Personalizable properties to values other than the default values.&lt;/p&gt;  &lt;p&gt;The categories in the Admin Panel went through extension partitioning during the design and initial beta testing.  By putting the administration related functions into a single page, a number of revelations were identified:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;What is the REAL purpose of the Web Part?      &lt;ul&gt;       &lt;li&gt;Cut out the fat in the Web Part &lt;/li&gt;        &lt;li&gt;Keep it simple, so that default properties make the Web Part usable when initially added to the page &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;What is the correct partitioning of the Web Parts? (A lot of User Experience discussions went into this stage)      &lt;ul&gt;       &lt;li&gt;How do users see administration being done? &lt;/li&gt;        &lt;li&gt;What is the travel required between Web Parts? &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;What administration-related Web Parts are missing?      &lt;ul&gt;       &lt;li&gt;It is easy to carried away in this stage – after all, we do love to write code:-) &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/image.png"&gt;&lt;img style="background-image: none; border-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" src="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/image_thumb.png" width="244" border="0" height="215" /&gt;&lt;/a&gt;   &lt;a href="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/image_3.png"&gt;&lt;img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" src="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/image_thumb_3.png" width="244" border="0" height="179" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Figure 1: CMS Admin Panel (shown for a logged in user)&lt;/p&gt;  &lt;p&gt;The left Admin Panel shows what a logged in user with the Admin role sees.  The right Admin Panel shows what a logged in user without the Admin role sees. Both are based on the default roles included in Web Parts.&lt;/p&gt;  &lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%;"&gt;&lt;span style="background-color: rgb(255, 255, 0);"&gt;&amp;lt;%&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Page&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;MasterPageFile&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"~/App_Master/W1MasterPage.master"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Title&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"Jetfire Administrator's Tools"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Consolas;"&gt; &lt;/span&gt;&lt;span style="background-color: rgb(255, 255, 0);"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%;"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="background-color: rgb(255, 255, 0);"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%;"&gt;&amp;lt;%&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Register&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;TagPrefix&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"cc1"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Namespace&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"TrackerRealm.WebPartsE"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Assembly&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"TrackerRealm.WebPartsE"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%;"&gt;&lt;span style="background-color: rgb(255, 255, 0);"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Content&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"Content2"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"server"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;ContentPlaceHolderID&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"ContentPlaceHolder1"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;table&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;width&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"100%"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;valign&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"top"&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;WebPartZone&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"Row1Column1"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"server"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;HeaderText&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"Row 1 Column 1"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ZoneTemplate&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;cc1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;AdminPanelPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"AdminPanelPart1"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"server"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ZoneTemplate&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;WebPartZone&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;    &amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;style&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;width&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;600px&lt;/span&gt;&lt;span&gt;;"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;WebPartZone&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"Row1Column2"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"server"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;HeaderText&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"Row 1 Column 2"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ZoneTemplate&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ZoneTemplate&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;WebPartZone&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;table&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Content&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 1: The Admin Panel in a Web Page&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;h3&gt;Admin Panel and Site Initialization&lt;/h3&gt;&lt;p&gt;The Admin Panel has real value during the design of a new website. View the page with the Admin Panel on it for a new site and the user is prompted to create a new user.  If there is at least one user present but the user is not logged in, then the user is prompted to login.  One of the requirements is that users MUST be logged in to use the Admin Panel.&lt;/p&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Check if there are users for this domain&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Membership&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.GetAllUsers().Count &amp;lt; 1)&lt;br /&gt;{ &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Starting Condition for system: Create User and Login&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddError(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"CreateErr"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Create a CMS User"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;CC&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddCreateUserPart(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Login"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Unit&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (!&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.LoginProfile.CP.IsAuthenticated)&lt;br /&gt;{ &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// User must login&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddError(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"LoginErr"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"CMS Login is required to access the CMS Admin Panel"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;CC&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddLoginPart(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Login"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Unit&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Consolas;" &gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 2:  Site Initialization code&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt;Panels&lt;/h3&gt;&lt;p&gt;Each major category in the menu is a Panel that hides and shows the links to Web Parts.  Code Snippet 3 shows the method call to create the panel.  The method takes an id, title, tooltip and parent control.&lt;/p&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Panel&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pnl = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AdminPanelPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddPanel(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Page"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Page Management"&lt;/span&gt;&lt;/span&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Tools to manage pages"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 3: Add a panel for the links&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Links to Web Parts are added to each panel. Since reflection is used to decide whether the Web Part is visible to the user, it is not known ahead of time what panels are displayed.  Therefore a simple test is used to check if the panel should be visible.&lt;/span&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Consolas;" &gt;pnl.Parent.Visible = pnl.Controls.Count &amp;gt; 0;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Consolas;" &gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 4: Show the panel ONLY IF it contains links&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;&lt;span&gt;Figure 2 shows the Admin Panel when a user has expanded the Page Management category.  There are 4 links, each displayed using the css class defined in the site’s stylesheet.&lt;/span&gt;&lt;/span&gt;&lt;pre style=""&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/CMSAdminPanel-ShowPageMenu.png"&gt;&lt;img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="CMSAdminPanel-ShowPageMenu" alt="CMSAdminPanel-ShowPageMenu" src="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/CMSAdminPanel-ShowPageMenu_thumb.png" width="244" border="0" height="165" /&gt;&lt;/a&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Figure 2: CMS Admin Panel showing the Page Management menu expanded&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt;Links&lt;/h3&gt;&lt;p&gt;Links for a set of Web Parts are added to the panel for each category.  The objective is to have a simple method for adding the link to the panel.  This method contains two parameters, the first for the type of Web Part being added and the second for the panel control that the link is added to.  So simple – bizarre, that it should take about 6 iterations before arriving at this.&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddLink(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;CreatePagePart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;), pnl);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 5: Add a Link to a category&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Code Snippet 6 shows the code used to add a link to the panel.  The Admin Panel Web Part exposes library and editor functions. That is why the logged in user must be able to enter share scope on the page.  Web Parts are dynamically added the first time that the Admin Panel is run in the &lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AdminPanelPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.&lt;/span&gt;&lt;/span&gt;GetWebPart method.  The Admin Panel Web Part has over 30 Web Parts that it dynamically creates and adds to the page. To display all Web Parts to the user at once is overwhelming, so the default is to hide all of the Web Parts that are dynamically added to the page.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Each Administration Web Part adheres to the IAdminRole interface, which identifies the visibility of the Web Part in the panel for the logged in user.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Finally, a link to the Web Part is included in the Admin Panel. A number of points about this:&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span&gt;The Web Part Title is displayed and the Web Part Description is used as a link mouseover.   By using reflection to find the Web Part on the page, the stored value of the Title and Description is retrieved from the Personalization Database to provide the customer with a customized Admin Panel. e.g. if the Customer does not like the Title: Update Page Meta Data, it is easy to change the title to something else which then is displayed in the Admin Panel.&lt;/span&gt; &lt;/li&gt;&lt;li&gt;&lt;span&gt;The LinkButton control is styled using the css classes.&lt;/span&gt; &lt;/li&gt;&lt;li&gt;&lt;span&gt;The Full Name of the Web Part is added to the command argument and is used in the event handler to display this Web Part as the visible Web Part.&lt;/span&gt; &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AddLink(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; t, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Control&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; parent)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;           if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (!&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.mgr.Personalization.CanEnterSharedScope)&lt;br /&gt;                   &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wp = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AdminPanelPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.GetWebPart(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.mgr, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.targetZone, t);&lt;br /&gt;        &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (wp == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;        {&lt;br /&gt;                   &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddError(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"NoWP"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + t.Name, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Cannot get Web Part: "&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + t.FullName);&lt;br /&gt;                   &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;        }&lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IAdminRole&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; admin = wp &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IAdminRole&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (admin != &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;{ &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Check that user is allowed access to the Web Part&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (!admin.IsAdminPanelVisible(admin.AdminRole))&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;     &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;LinkButton&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; link = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddLinkButton(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"link"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + t.Name, wp.Title, wp.Description, linkCssClass, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Unit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Percentage(100), parent);&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;     &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddStyle(link, linkCssClass, mouseOverCssClass);&lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddBreak(1, parent);&lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;link.CommandArgument = t.FullName;&lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;link.Command += &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;CommandEventHandler&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(link_Command);&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 6: Code for adding a link&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;&lt;span&gt;The GetWebPart method looks through all Web Parts in the page for the requested Web Part. (this means that a single instance of any Web Part is included on the page.)  If the requested Web Part is not found, then the Web Part is dynamically created (this will be the subject of another blog article).  Finally, properties are set in the Web Part and the found Web Part is returned up the stack.&lt;/span&gt;&lt;/span&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; GetWebPart(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPartManager&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; mgr, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; targetZone, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; t)&lt;br /&gt;{&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wp1 &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; mgr.WebParts)&lt;br /&gt; {&lt;br /&gt;  &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (wp1.GetType().FullName != t.FullName)&lt;br /&gt;   &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;continue&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;  &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wp1;&lt;br /&gt; }&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; error = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty;&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wp = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;L&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.CreateWebPart(mgr, t.FullName, targetZone, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;ref&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; error);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (wp == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;  &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Exception&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Cannot create: "&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + t.FullName + &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;" "&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; + error);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ITWebPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; iwp = wp &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ITWebPart&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (iwp != &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;  iwp.LoginType = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;LoginType&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.COR;&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wp;&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 7: Get the requested Web Part&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;&lt;span&gt;When the user clicks a link for a specific Web Part, the code in Code Snippet 8 is invoked.  The variable, ‘wpTypes’ (Web Part Types) is a list of strings, i.e. the Full Names of the Web Parts to be displayed to the user.  The list is stored in the ViewState, thus keeping the Web Part visible until it is no longer required.&lt;/span&gt;&lt;/span&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; link_Command(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sender, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;CommandEventArgs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; e)&lt;br /&gt;{&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wpType = e.CommandArgument.ToString();&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.wpTypes.Clear();&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.wpTypes.Add(wpType);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 8: Display the Web Part&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt;Admin Roles Interface&lt;/h3&gt;&lt;p&gt;One of the goals of the Admin Panel is to highly customizable for each customer.  It is typical that each customer partitions the work done in the organization differently.  Therefore, it is important that the tools can be molded to how the customer wants to use them.&lt;/p&gt;&lt;p&gt;Initially, the links were added to the page by instantiating the Web Part type.  The problem with this approach is that the default properties are present.  It became clear quickly that Reflection was required to get the Web Part on the page and the properties that may have been changed by the customer.  The Admin Role interface was a simple way to identify what roles were allowed access to each administration Web Part and hence whether it was visible to the logged in user.&lt;/p&gt;&lt;p&gt;By having each Administration Web Part adhering to the IAdminRole interface, this simplified the code and created consistency across the Admin Panel user interface usage.&lt;/p&gt;&lt;blockquote&gt;&lt;p style="line-height: normal; margin: 0in 0in 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IAdminRole&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span style=""&gt;           &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; A comma-delimited list of Roles that are allowed to use the Web Part.  &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=""&gt;           &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Used in association with Web Part that use the Admin Panel.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=""&gt;           &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=""&gt;           &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt; AdminRole&lt;br /&gt;&lt;span style=""&gt;           &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;{&lt;br /&gt;&lt;span style=""&gt;                       &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&lt;span style=""&gt;                       &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&lt;span style=""&gt;           &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;}&lt;br /&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Used by the Admin Panels to identify that the Web Part is visible to the user&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;param name="roles"&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;A comma-delimited list of Roles&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;true is the Web Part is visible in the Admin Panel&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&lt;/span&gt; IsAdminPanelVisible(&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;/span&gt; roles);&lt;br /&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="line-height: normal; margin: 0in 0in 0pt;" class="MsoNormal"&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 9: IAdminRole interface&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;My Links&lt;/h3&gt;&lt;p&gt;The ‘My Links’ feature was simple to add. Just get the links from the Navigation Xml File and add each link as a LinkButton to the Web Part as part of the ‘My Links’ panel.  Note that the method Link.Get includes a LoginProfile.  This ensures that the links displayed match the roles of the logged in user.&lt;/p&gt;&lt;pre style=""&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.navLinksFile != &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty)&lt;br /&gt;{&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;XmlDocument&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; doc = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.ReadXmlFile(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.navLinksFile);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Link&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt; links = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Link&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Get(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Context, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.LoginProfile, doc);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Link&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt; myLinks = links.FindAll(l =&amp;gt; l.MenuName == &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.menuName);&lt;br /&gt; &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (myLinks.Count &amp;gt; 0)&lt;br /&gt; {&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  Panel pnl = &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AdminPanelPart&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddPanel(&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"MyLinks"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"My Links"&lt;/span&gt;&lt;/span&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Display a set a site favourite links"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;  &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; i = 0;&lt;br /&gt;  &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Link&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; link &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; myLinks)&lt;br /&gt;  {&lt;br /&gt;   &lt;/span&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.AddLink(i, link, pnl);&lt;br /&gt;   i++;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=""&gt;&lt;span style="color: rgb(0, 0, 255);font-family:Consolas;" &gt;&lt;span&gt;Code Snippet 10: Adding My Links to the Admin Panel&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt;The Last Word&lt;/h3&gt;&lt;p&gt;As mentioned above, over 30 Web Parts are present on the Admin Panel page. When Editing the page, it is very confusing UNLESS the content of each Web Part is invisible, as shown in Figure 3.&lt;/p&gt;&lt;p&gt;Another comment is that the page with the Admin Panel should deny logged in users edit and catalog access. By doing this, as the user navigates the site, they do not have to manually change from Edit/Catalog to Browse mode for the Admin Panel page.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/CMSAdminPanel-EditMode.png"&gt;&lt;img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="CMSAdminPanel-EditMode" alt="CMSAdminPanel-EditMode" src="http://www.trackerrealm.com/blogimagesmore/Design_D6AC/CMSAdminPanel-EditMode_thumb.png" width="495" border="0" height="379" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Trebuchet MS;" &gt;Figure 3: CMS Admin Panel in Edit Mode&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-7826213602738540826?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/7826213602738540826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=7826213602738540826' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7826213602738540826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7826213602738540826'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/10/design-for-web-part-based-admin-panel.html' title='Design for a Web Part-based Admin Panel'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-3222615957034072133</id><published>2010-09-22T14:11:00.000-04:00</published><updated>2010-10-22T15:38:31.039-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Specification for a Web Part-based Admin Panel</title><content type='html'>&lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/SpecificationforaWebPartbasedAdminPanel_9046/CMSAdminPanelLogin.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="CMSAdminPanel-Login" border="0" alt="CMSAdminPanel-Login" align="right" src="http://www.trackerrealm.com/blogimagesmore/SpecificationforaWebPartbasedAdminPanel_9046/CMSAdminPanelLogin_thumb.png" width="244" height="124" /&gt;&lt;/a&gt; Building Web 2.0 enabled websites with COR – a website Content Management System and Jetfire – a workflow language means a powerful, flexible set of Web Parts available for building websites from scratch. The ASP.NET Web Part is a Microsoft custom control that is used to personalize websites. Properties in the Web Part may be decorated with the Personalization attribute that indicates that the value of the property will be stored in a database. Web Parts can easily be added to a web page from a library and then edited, saving the changes in a personalization database that comes with Visual Studio. Web Parts were initially included in Visual Studio 2.0 and owe their specification to SharePoint.&lt;/p&gt;  &lt;p&gt;So what’s the problem? With over 100 Web Parts available to build a website, navigation to the right Web Part for inclusion on the page becomes the issue. Is there a simpler way to get the Web Part that is needed when it is needed?&lt;/p&gt;  &lt;h4&gt;Organizing Web Parts&lt;/h4&gt;  &lt;p&gt;ASP.NET Web Parts are organized in a set of catalogues with each catalogue consisting of a set of Web Parts that perform a function in a similar area, e.g. a catalogue for navigation Web Parts.&lt;/p&gt;  &lt;p&gt;As COR was used for more websites, designer and debugging Web Parts were included.&lt;/p&gt;  &lt;h5&gt;WebPartDisplayMode&lt;/h5&gt;  &lt;p&gt;The Web Part Display Mode enumeration tracks what Zones on a page are visible and what actions can be performed on the Web Part Zone. This enumeration includes (for purposes of this article):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Browse &lt;/li&gt;    &lt;li&gt;Catalog &lt;/li&gt;    &lt;li&gt;Edit &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The life-cycle for a Web Part on a web page can be described as:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Find the Web Part that you want added to the page      &lt;ol&gt;       &lt;li&gt;The Web Part Display Mode is set to Catalog. This displays the Web Part library in the Catalog Zone. &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;Select the Web Part that you want added to the page from a Web Part Catalog. &lt;/li&gt;    &lt;li&gt;Add the Web Part by selecting a Zone on the page and clicking the Add button in the Web Part Library. &lt;/li&gt;    &lt;li&gt;Change the Web Part Display Mode to Edit. &lt;/li&gt;    &lt;li&gt;Edit the Web Part added to the page.      &lt;ol&gt;       &lt;li&gt;The properties of the Web Part are displayed in the Editor Zone. &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;Set the properties and click Ok. This saves the properties to the Personalization Database.      &lt;ol&gt;       &lt;li&gt;Clicking Ok also closes the editor for the Web Part. &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;Change the Web Part Display Mode to browse.      &lt;ol&gt;       &lt;li&gt;The Web Part is displayed as any visitor to the web page would see it. &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;Simplify, Simplify, Simplify&lt;/h4&gt;  &lt;p&gt;Any web site, whether it is 3 pages or 100 pages, has a number of required functions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Page administration, e.g. Create a page, upload files &lt;/li&gt;    &lt;li&gt;Site Administration, e.g. site navigation &lt;/li&gt;    &lt;li&gt;Web Part Tools, e.g. assign roles to a folder &lt;/li&gt;    &lt;li&gt;User management, create a user, edit a user &lt;/li&gt;    &lt;li&gt;Roles management, create a role, edit a role, assign roles to a user &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimagesmore/SpecificationforaWebPartbasedAdminPanel_9046/CMSAdminPanelStart.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="CMSAdminPanel-Start" border="0" alt="CMSAdminPanel-Start" align="left" src="http://www.trackerrealm.com/blogimagesmore/SpecificationforaWebPartbasedAdminPanel_9046/CMSAdminPanelStart_thumb.png" width="244" height="131" /&gt;&lt;/a&gt;This set of functions represents over 20 CMS Web Parts that if positioned on separate pages would fill up to ten pages. That represents a lot of real estate on a website with navigation making it difficult to find the necessary function.&lt;/p&gt;  &lt;p&gt;Certainly, we need to find a way to simplify how we find and access these Web Parts. The key questions are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is it possible to host these Web Parts on a single page? &lt;/li&gt;    &lt;li&gt;How do we simplify the navigation? &lt;/li&gt;    &lt;li&gt;How do we simplify the interface, so that we are not overwhelmed with too many Web Parts on the page? &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;The Admin Panel as the alternative interface&lt;/h4&gt;  &lt;p&gt;The Admin Panel is the alternative interface that combined the catalogue, edit and browse functions to create a highly functional, yet compact interface. By combining catalogue, edit and browse into a single control, the interface is simplified to these steps:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Find the Web Part that you want to use by navigating the Admin Panel navigation menu. &lt;/li&gt;    &lt;li&gt;If the Web Part is not added to the page, then the Admin Panel code adds the Web Part automatically to the page. &lt;/li&gt;    &lt;li&gt;The Web Part is displayed. &lt;/li&gt;    &lt;li&gt;Wow – that simplifies how Web Parts are found and added to the page. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The Admin Panel can add a number of Web Parts to the page. If all of the Web Parts are visible on the page, this can be very confusing to the Administrator. Therefore, it is important to include a technique where all Web Parts, except the chosen one are hidden.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://www.trackerrealm.com/blogimagesmore/SpecificationforaWebPartbasedAdminPanel_9046/CMSAdminPanelStartManageUsers.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="CMSAdminPanel-Start-ManageUsers" border="0" alt="CMSAdminPanel-Start-ManageUsers" src="http://www.trackerrealm.com/blogimagesmore/SpecificationforaWebPartbasedAdminPanel_9046/CMSAdminPanelStartManageUsers_thumb.png" width="499" height="186" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The above figure shows the CMS Admin Panel with the User Management and Role Management options displayed.&amp;#160; The Manage CMS Users Web Part is displayed beside the CMS Admin Panel.&lt;/p&gt;  &lt;h4&gt;Admin Panel Strengths&lt;/h4&gt;  &lt;p&gt;By using the Admin Panel, there are a number of advantages for the website. These include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A single page implementation for designer and debugging functions &lt;/li&gt;    &lt;li&gt;Access to over 20 Web Parts on a single page &lt;/li&gt;    &lt;li&gt;Reduced navigation and number of pages in the website for managing the site &lt;/li&gt;    &lt;li&gt;The active Web Part is displayed alone on the page &lt;/li&gt;    &lt;li&gt;A navigation menu on the Admin Panel presents the choices, making selection of the correct function easy &lt;/li&gt;    &lt;li&gt;New system start-up prompts the user to create a new CMS user (when there are no users present) &lt;/li&gt;    &lt;li&gt;Admin Panel start-up prompts the user to login (you must be logged in to use the Admin panel) &lt;/li&gt;    &lt;li&gt;Access to multiple websites (Forms Authentication and the Personalization Database supports multiple websites from a single database) &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-3222615957034072133?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/3222615957034072133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=3222615957034072133' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3222615957034072133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3222615957034072133'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/09/specification-for-web-part-based-admin.html' title='Specification for a Web Part-based Admin Panel'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8169272781206735852</id><published>2010-07-10T11:03:00.001-04:00</published><updated>2010-09-17T18:53:08.462-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic Object'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><category scheme='http://www.blogger.com/atom/ns#' term='DLR'/><title type='text'>Dynamic Languages – Why all the fuss?</title><content type='html'>&lt;p&gt;Lately there has been a surge of interest in dynamic languages, especially in the .net world with introduction of &lt;a href="http://en.wikipedia.org/wiki/C_Sharp_4.0"&gt;C# 4.0&lt;/a&gt; that&amp;#160; both gives C# dynamic language features and enables creation of dynamic languages with &lt;a href="http://dlr.codeplex.com/"&gt;DLR&lt;/a&gt;.&amp;#160;&amp;#160; The short answer is that dynamic languages, such as Python and JavaScript, are part of a technology evolutionary process that supports developing application software that is both faster to write and faster to deploy.&amp;#160;&amp;#160; Dynamic languages are also part of a trend of new &lt;a href="http://yourdotnetdesignteam.blogspot.com/2009/03/why-domain-specific-language-is-better.html"&gt;‘Domain Specific Languages’ replacing traditional frameworks&lt;/a&gt;.&amp;#160; Domain Specific Languages are typically dynamic languages as well.&lt;/p&gt;  &lt;p&gt;So what is a dynamic language?&amp;#160;&amp;#160; The &lt;a href="http://en.wikipedia.org/wiki/Dynamic_programming_language"&gt;basic definition of dynamic language&lt;/a&gt; is one that performs operations at runtime that other languages perform at compile time or perform in multiple statements (if the operation can be performed at all).&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a href="http://imgs.xkcd.com/comics/compiling.png"&gt;&lt;img style="margin: 0px 0px 0px 10px; display: inline" title="click to enlarge" alt="click to enlarge" align="right" src="http://imgs.xkcd.com/comics/compiling.png" width="173" height="151" /&gt;&lt;/a&gt;Dynamic typing&lt;/strong&gt;:&amp;#160; This is the most significant attribute of many dynamic languages (and also a source of criticism).&amp;#160; With this feature type checking is performed at runtime.&amp;#160;&amp;#160; This has a number of advantages such as&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;run time binding (note cartoon)&amp;#160; &lt;/li&gt;    &lt;li&gt;less code therefore faster development &lt;/li&gt;    &lt;li&gt;no need to create interfaces &lt;/li&gt;    &lt;li&gt;greatly reduces the need to create wrapper classes &lt;/li&gt;    &lt;li&gt;supports Multiple Dispatch (dynamic method calls)&lt;/li&gt;    &lt;li&gt;enables other dynamic language features &lt;/li&gt; &lt;/ul&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="579"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="158"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="99"&gt;         &lt;p align="center" margin:="margin:" 0px;style="padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&lt;strong&gt;C# (rel 4.0)&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="88"&gt;         &lt;p align="center" margin:="margin:" 0px;style="padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="111"&gt;         &lt;p align="center" margin:="margin:" 0px;style="padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&lt;strong&gt;Javascript&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="121"&gt;         &lt;p align="center"&gt;&lt;strong&gt;&lt;a href="http://www.jetfire.ca"&gt;Jetfire&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="157"&gt;         &lt;p style="margin: 0px" align="left"&gt;Dynamic typing            &lt;br /&gt;(aka &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;Duck typing&lt;/a&gt;)&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="98"&gt;         &lt;p style="margin: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="91"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes &lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="112"&gt;         &lt;p style="margin: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="margin: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="156"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="left"&gt;Strongly Typed&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="91"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes &lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="113"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;Interface&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="92"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="113"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;Run time binding&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="92"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="113"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;Type Checking&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p align="center"&gt;compile and runtime&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="92"&gt;         &lt;p align="center"&gt;runtime&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="113"&gt;         &lt;p align="center"&gt;runtime&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p align="center"&gt;compile and runtime&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;Roles&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="92"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="113"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;Dynamic Access Modifiers&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="92"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="113"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;Integrated ORM&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="92"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="113"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;Integrated SVC&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="93"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="114"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px" align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="155"&gt;&lt;a href="http://en.wikipedia.org/wiki/Multiple_dispatch"&gt;Multiple Dispatch&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="97"&gt;         &lt;p align="center"&gt;&amp;#160;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/test_06.html"&gt;with dynamic&lt;/a&gt;            &lt;br /&gt;or extension&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="93"&gt;         &lt;p align="center"&gt;&lt;a href="http://en.wikipedia.org/wiki/Multiple_dispatch#Python"&gt;with extension&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="114"&gt;         &lt;p align="center"&gt;no&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="120"&gt;         &lt;p align="center"&gt;yes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;Criticism&lt;/strong&gt;:&amp;#160; Dynamic languages have their share of critics.&amp;#160;&amp;#160; Many software developers believe that dynamic languages merely shift type checking problems to runtime.&amp;#160; In a non-dynamic language type checking is performed by the compiler, catching many errors before the code is ever executed.&amp;#160;&amp;#160; With most dynamic languages typing errors are only caught at run time with real data. This rub is that a non-dynamic language applications still need to simulate dynamic typing thereby introducing the possibility of runtime errors. This handicap also needs to balanced with the other benefits of dynamic typing.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a href="http://codinghorror.typepad.com/.a/6a0120a85dcdae970b012877707a45970c-pi"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" title="click to enlarge" alt="click to enlarge" align="right" src="http://codinghorror.typepad.com/.a/6a0120a85dcdae970b012877707a45970c-pi" width="200" height="181" /&gt;&lt;/a&gt;Summary:&lt;/strong&gt; My view on this criticism is I have heard it all before.&amp;#160;&amp;#160; This debate has been going on since the beginning of the computer age.&amp;#160; Whether the issue be high level languages vs assembler (yes many programmers argued against using high level languages) or managed code vs compiled code there has always been detractors arguing for the status quo.&amp;#160;&amp;#160; Helping blunt their criticism has been technology improvements where compilers generate code nearly as good as hand assembled code and managed code/byte code (&lt;a href="http://en.wikipedia.org/wiki/Managed_code"&gt;.net&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Java_(programming_language)"&gt;Java&lt;/a&gt;) becomes almost indistinguishable from compiled code.&amp;#160;&amp;#160; The same will be true for dynamic languages as new languages and new releases aim to fix these issues.&lt;/p&gt;  &lt;p&gt;The bottom line is any new technology, such as dynamic languages and domain specific languages, that supports better programmer productivity will win out. &lt;/p&gt;  &lt;p&gt;Excellent, but long video on this subject:&amp;#160; &lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=tz-Bb-D6teE"&gt;Dynamic Languages Strike Back&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8169272781206735852?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8169272781206735852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8169272781206735852' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8169272781206735852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8169272781206735852'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/07/dynamic-languages-why-all-fuss.html' title='Dynamic Languages – Why all the fuss?'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-6659435679300959315</id><published>2010-06-25T15:31:00.001-04:00</published><updated>2010-09-17T18:54:04.952-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Tips to Prevent .net Memory Leaks</title><content type='html'>&lt;p&gt;&lt;a href="http://www.cartoonstock.com/newscartoons/cartoonists/dpa/lowres/dpan1096l.jpg"&gt;&lt;img style="margin: 0px 10px 0px 0px; display: inline" title="click to enlarge" alt="click to enlarge" align="left" src="http://www.cartoonstock.com/newscartoons/cartoonists/dpa/lowres/dpan1096l.jpg" width="142" height="200" /&gt;&lt;/a&gt; Microsoft .net has a built-in garbage collector, yet programs can contain &lt;a href="http://en.wikipedia.org/wiki/Memory_leak"&gt;memory leaks&lt;/a&gt;.&amp;#160;&amp;#160; Many times these memory leaks show up during testing in Visual Studio with the dreaded&amp;#160; “Out of Memory” error.&amp;#160;&amp;#160; This is a good thing allowing the problem to be identified and fixed.&amp;#160; Sometimes the units tests are themselves the cause of the memory leak casting suspicion on the validity of the tests or masking real problems that would otherwise by uncovered by the test.&amp;#160;&amp;#160; This is not good.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/salim/53178920/"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://farm1.static.flickr.com/29/53178920_88c95482c2_o.jpg" width="198" height="152" /&gt;&lt;/a&gt;The first question to answer is how can a memory leak occur in the first place?&amp;#160; After all .net has a &lt;a href="http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx"&gt;garbage collector&lt;/a&gt; that should prevent memory leaks.&lt;/p&gt;  &lt;p&gt;&amp;#160; The garbage collector works by collecting unreferenced memory.&amp;#160;&amp;#160; When it can’t collect some object it is because there is a reference to it.&amp;#160;&amp;#160; There are 2 main culprits, namely, static collections and threads.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Threads&lt;/u&gt;&lt;/strong&gt; will release their memory when they terminate.&amp;#160;&amp;#160; Threads fail to terminate either because they are waiting for a resource or are stuck in a ‘while(forever)’ loop.&amp;#160;&amp;#160; The good news is that by using the Visual Studio ‘Threads’ window it is easy to spot threads that have not terminated.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Static collections&lt;/u&gt;&lt;/strong&gt; can easily cause memory leaks.&amp;#160;&amp;#160; This because the static field storing the reference to the collection is present as long as the program is operating.&amp;#160; The collections can also be hidden inside other objects, for example &lt;a href="http://msdn.microsoft.com/en-us/library/awbftdfh.aspx"&gt;C# Events&lt;/a&gt; are collections therefore a static event is really a static collection.&amp;#160; Also be aware that long lived collections, be they system objects or in your code, can behave as static collections retaining references to unused objects.&lt;/p&gt;  &lt;p style="margin-bottom: -10px"&gt;The single best way to eliminate most, if not all, memory leaks is to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;employ the &lt;a href="http://msdn.microsoft.com/en-us/library/yh598w02.aspx"&gt;‘using’ construct&lt;/a&gt; (or alternately &lt;a href="http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx"&gt;try-finally construct&lt;/a&gt;) for objects that support the &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx"&gt;“Idisposable” interface&lt;/a&gt;.&amp;#160;&amp;#160; &lt;/li&gt;    &lt;li&gt;Make classes that create threads or add objects to static or a long lived collection &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx"&gt;IDisposable&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The following C# code demonstrates employing the ‘using’ construct when working with the Linq-to-Sql ‘&lt;a href="http://msdn.microsoft.com/en-us/library/bb298245.aspx"&gt;DataContext&lt;/a&gt;’ object&amp;#160; (also see &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html"&gt;using DataContext example&lt;/a&gt;).&amp;#160; The Dispose method is automatically called upon exit of the using block.&amp;#160;&amp;#160; The ‘Dispose’ method will be called even if an&amp;#160; exception occurs within the ‘using’ block.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="668"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="666"&gt;         &lt;blockquote style="background: #efeff7"&gt;           &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; color: blue; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;using&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt; (&lt;span style="color: #2b91af"&gt;DataContext&lt;/span&gt; dc = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MyDataContext&lt;/span&gt;(connectionString))                 &lt;br /&gt;{                 &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: green"&gt;// &lt;/span&gt;                &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: green"&gt;// work with ‘DataContext’ object&lt;/span&gt;                 &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: green"&gt;//                  &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: green"&gt;&amp;#160;&amp;#160;&amp;#160; // Dispose method &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: green"&gt;is called &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: green"&gt;automatically upon exit of the using block.                  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // The Dispose method will be called even if an exception occurs                   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // within the ‘using’ block.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: green"&gt;                  &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;} &lt;/span&gt;&lt;/p&gt;         &lt;/blockquote&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Summary: Tips To Prevent Memory Leaks&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Don’t use static collections or static events unless absolutely necessary. &lt;/li&gt;    &lt;li&gt;Add the IDisposable interface (and write a Dispose Method) to any class that:&amp;#160; &lt;ul&gt;       &lt;li&gt;Adds an object to static or long lived collection &lt;/li&gt;        &lt;li&gt;Adds a event handler a static&amp;#160; or long lived ‘Event’&amp;#160; (events are collections) &lt;/li&gt;        &lt;li&gt;Creates a thread &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Use the “Using” construct to insure the ‘Dispose’ method executes for an &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx"&gt;IDisposable&lt;/a&gt; object.       &lt;ul&gt;       &lt;li&gt;This is very helpful when creating Unit Tests.&amp;#160; Unit test themselves can easily be the cause of the memory leak if they don’t employ the ‘using’ construct. &lt;/li&gt;        &lt;li&gt;The ‘using’ construct should be employed when creating DataContext objects with ‘linq-to-sql’.&amp;#160;&amp;#160; This will insure that the DataContext objects are disposed properly, as they will not release memory by simply being dereferenced. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Alternately if the using statement is not practical, then use the ‘try-catch-finally’ construct placing the ‘Dispose’ method in ‘finally’ code section.&amp;#160;&amp;#160; Remember you don’t need to catch exceptions, you can simply use &lt;a href="http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx"&gt;‘try’ and ‘finally’&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Further Reading   &lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/20386/memory-leaks-in-net"&gt;stackoverflow thread on memory leaks in .net&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee658248.aspx"&gt;How to detect and avoid memory and resources leaks in .NET applications&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-6659435679300959315?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/6659435679300959315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=6659435679300959315' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6659435679300959315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6659435679300959315'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/tips-to-prevent-net-memory-leaks.html' title='Tips to Prevent .net Memory Leaks'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-984197830645703771</id><published>2010-06-25T09:14:00.001-04:00</published><updated>2010-06-25T18:11:02.615-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic Object'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><category scheme='http://www.blogger.com/atom/ns#' term='DLR'/><title type='text'>Marthon Jetfire Application Example</title><content type='html'>&lt;p&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-v12-allows-applications-to-have.html"&gt;&lt;img style="margin: 0px 10px 0px 0px; display: inline" align="left" src="http://farm1.static.flickr.com/105/253527065_2b5f4d57b9.jpg" width="168" height="126" /&gt;&lt;/a&gt; This example demonstrates how to use the &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/integrated-orm-in-jetfire-v12.html"&gt;integrated ORM feature&lt;/a&gt; of &lt;a href="http://jetfire.ca"&gt;Jetfire&lt;/a&gt; to be able support an &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-v12-allows-applications-to-have.html"&gt;almost unlimited number of objects&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;In this example a Marathon registration system is required to handle over 100,000 athletes.&amp;#160;&amp;#160; A Jetfire object will be used to represent each athlete.&amp;#160; Over time, as the application grows, there may be multiple objects for each athlete.&amp;#160;&amp;#160; For performance and resource utilization reasons it is desirable that only the objects representing the athletes that are currently of interest reside in the processor memory.&lt;/p&gt;  &lt;p&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://3.bp.blogspot.com/_WqqRGkoDIG0/TCSyjLBo90I/AAAAAAAAAB0/mE3ovJWCJLs/s1600/microsoft_sql_logo.png" width="133" height="83" /&gt;Naturally we want all the objects to be permanently stored in a database.&amp;#160; Jetfire meets these&amp;#160; requirements by transparently storing all objects in a searchable database (SQL server 2008 is preconfigured).&amp;#160;&amp;#160; The database can be searched using a linq style construct from either Jetfire code or .net application code.&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;Here is the Jetfire code representing an athlete.&amp;#160;&amp;#160; The object is quite simple, but can easily be extended by adding more attributes.&amp;#160;&amp;#160; Later examples will&amp;#160; show to add features such as a approval process and how to allow each individual athlete to update their own information.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="578"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="576"&gt;         &lt;blockquote style="background: #efeff7"&gt;           &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; color: #a31515; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;namespace Marathon                &lt;br /&gt;{                 &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; color: #a31515; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&amp;#160; public workflow Runner&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;                &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160; {&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;// A workspace where the 'runner' objects reside.&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;static workspace wsRunners;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public static void InitializeRunner()&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;wsRunners = new workspace(&amp;quot;&amp;quot;Runners&amp;quot;&amp;quot;);&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;// The contents of the workspace are only to be cached &lt;/span&gt;                &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;// in the client nexus when they are explicitly referenced.&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;wsRunners.IsAutoCached = false;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public static Runner NewRunner(string firstName, string lastName)&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;Runner r = new Runner()&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;at root in wsRunners;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;r.FirstName = firstName;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;r.LastName = lastName;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;return r;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public string FirstName&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;get;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;private set;&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public string LastName&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;                &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;get;&lt;/span&gt;&amp;#160; &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; color: #a31515; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;private set;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;                &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160; }                  &lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;         &lt;/blockquote&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;blockquote&gt;&lt;/blockquote&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;/p&gt;  &lt;p&gt;The method “&lt;font color="#800000"&gt;InitializeRunner&lt;/font&gt;” creates a workspace named “&lt;font color="#800000"&gt;wsRunners&lt;/font&gt;” which is used to store the athlete objects called “Runner”.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://gabrielutasi.com/080307.computer_programmer.gif"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" title="Click to enlarge" alt="Click to enlarge" align="right" src="http://gabrielutasi.com/080307.computer_programmer.gif" width="203" height="139" /&gt;&lt;/a&gt;The method “&lt;font color="#800000"&gt;NewRunner&lt;/font&gt;” creates a athlete object using the &lt;a href="http://wiki.jetfire.ca/Workflow.ashx#Jetfire_new_Operator_0"&gt;‘new’ construct&lt;/a&gt;.&amp;#160;&amp;#160; The ‘&lt;font color="#800000"&gt;at Root&lt;/font&gt;’ specifies the garbage collector is not collect this object even though it may have no references.&amp;#160;&amp;#160; The garbage collector will collect ‘Runner’ objects when they are explicitly deleted.&amp;#160; The “&lt;font color="#800000"&gt;in wsRunners&lt;/font&gt;” specifies to store the object in the workspace.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;The following shows .net C# code used to create athlete objects.&amp;#160; Note the .net code can call Jetfire methods directly.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="612"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="610"&gt;         &lt;blockquote style="background: #efeff7"&gt;           &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;nexus.Parse(jetfireCode);                &lt;br /&gt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; runnerClass = nexus.FindClass&amp;lt;&lt;span style="color: #2b91af"&gt;WorkflowClass&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Marathon.&lt;/span&gt;&lt;span style="color: #a31515"&gt;Runner&amp;quot;&lt;/span&gt;);                 &lt;br /&gt;runnerClass.InitializeRunner();                 &lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: consolas; color: green; font-size: 9.5pt; mso-bidi-font-family: consolas; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;//&lt;/span&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;                &lt;br /&gt;&lt;span style="color: green"&gt;// create some runners – automatically stored in database&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: green"&gt;//                  &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;runnerClass.NewRunner(&lt;span style="color: #a31515"&gt;&amp;quot;Bob&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Weave&amp;quot;&lt;/span&gt;);&lt;/span&gt;               &lt;br /&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;runnerClass.NewRunner(&lt;span style="color: #a31515"&gt;&amp;quot;Bob&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Best&amp;quot;&lt;/span&gt;);                 &lt;br /&gt;runnerClass.NewRunner(&lt;span style="color: #a31515"&gt;&amp;quot;Long&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Distance&amp;quot;&lt;/span&gt;);                 &lt;br /&gt;runnerClass.NewRunner(&lt;span style="color: #a31515"&gt;&amp;quot;Harry&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Heart&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;         &lt;/blockquote&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p style="margin-bottom: 0px"&gt;To search the database for objects the following construct can be used.&amp;#160;&amp;#160; Searching can also be performed in Jetfire code.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="608"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="606"&gt;         &lt;blockquote style="background: #efeff7"&gt;           &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; color: green; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;//&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;                &lt;br /&gt;&lt;span style="color: green"&gt;// Search the database by executing the system library                  &lt;br /&gt;// static method 'Nexus.Search()'.&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: green"&gt;//&lt;/span&gt;                 &lt;br /&gt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;[] runners = nexus.NexusClass.Execute&amp;lt;&lt;span style="color: #2b91af"&gt;Workflow&lt;/span&gt;[]&amp;gt;                 &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span style="color: #a31515"&gt;&amp;quot;Search&amp;quot;&lt;/span&gt;,                 &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #a31515"&gt;&amp;quot;Marathon.Runner&amp;quot;&lt;/span&gt;,                 &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #a31515"&gt;@&amp;quot;w.FirstName == &amp;quot;&amp;quot;Bob&amp;quot;&amp;quot; &amp;quot;&lt;/span&gt;);                 &lt;br style="mso-special-character: line-break" /&gt;&lt;/span&gt;&lt;/p&gt;            &lt;p&gt;&lt;/p&gt;            &lt;p&gt;&lt;/p&gt;         &lt;/blockquote&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt; For a complete listing search for ‘MarathonTest.cs’ in the &lt;a href="http://jetfire.codeplex.com"&gt;codeplex download&lt;/a&gt;.   &lt;p&gt;See also    &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-object-persistence-is-tip-of.html"&gt;Persistence is the Tip of the Iceberg&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-v12-allows-applications-to-have.html"&gt;Applications can have unlimited objects&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-objects-now-support-net-dlr.html"&gt;Using Jetfire Dynamic Objects in C#&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/build-large-applications-with-kiss.html"&gt;Build Large Applications with Jetfire KISS&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-984197830645703771?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/984197830645703771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=984197830645703771' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/984197830645703771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/984197830645703771'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/marthon-jetfire-application-example.html' title='Marthon Jetfire Application Example'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm1.static.flickr.com/105/253527065_2b5f4d57b9_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-6723851362472878823</id><published>2010-06-18T09:00:00.001-04:00</published><updated>2010-07-01T07:18:05.077-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic Object'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><category scheme='http://www.blogger.com/atom/ns#' term='DLR'/><title type='text'>Jetfire objects now Support .net DLR</title><content type='html'>&lt;p&gt;&lt;img style="margin: 0px 10px 10px 0px; display: inline" align="left" src="http://jetfire.ca/Images/dotnet.png" width="70" height="67" /&gt;Jetfire provides .net programmers &lt;a href="http://wiki.jetfire.ca/First%20Class%20Constructs.ashx"&gt;many features&lt;/a&gt; not found in the standard languages.&amp;#160; Mixing Jetfire code and .net code has always been a straight forward task.&amp;#160; Now, with Jetfire Dynamic Language Runtime (&lt;a href="http://en.wikipedia.org/wiki/Dynamic_Language_Runtime"&gt;DLR&lt;/a&gt;) objects that task has been made much easier.&amp;#160; Using Visual Studio 2010 Jetfire objects can now be accessed directly from .net languages.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cartoonstock.com/newscartoons/cartoonists/mmo/lowres/mmon109l.jpg"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" title="click to enlarge" alt="click to enlarge" align="right" src="http://www.cartoonstock.com/newscartoons/cartoonists/mmo/lowres/mmon109l.jpg" width="204" height="87" /&gt;&lt;/a&gt;DLR allows .net programmers to very easily use Jetfire objects in their applications as shown the following example:&lt;/p&gt;  &lt;p&gt;Here is a simple Jetfire program.&lt;/p&gt;  &lt;blockquote style="background: #efeff7"&gt;   &lt;p&gt;&lt;span style="line-height: 115%; font-family: consolas; color: #a31515; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;namespace DlrExample &lt;/span&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;       &lt;br /&gt;&lt;span style="color: #a31515"&gt;{&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public workflow MyFlow&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public string MyString{get; set;}&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public string MyAction(){ return this.MyString;}&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;public string MyAction(string s){return s;}&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: #a31515"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: #a31515"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;&lt;span style="color: #a31515"&gt;&lt;/span&gt;To work with Jetfire objects the following C# code can be used.&lt;/span&gt;&lt;/p&gt;  &lt;blockquote style="background: #efeff7"&gt;   &lt;p&gt;&lt;span style="line-height: 115%; font-family: consolas; color: blue; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;dynamic&lt;/span&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt; myFlow = nexus.New&amp;lt;&lt;span style="color: #2b91af"&gt;Workflow&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;&amp;quot;DlrExample.MyFlow&amp;quot;&lt;/span&gt;);         &lt;br /&gt;&lt;span style="color: green"&gt;//&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: green"&gt;// Access the Workflow's properties and methods&lt;/span&gt;         &lt;br /&gt;&lt;span style="color: green"&gt;// &lt;/span&gt;        &lt;br /&gt;myFlow.MyString = &lt;span style="color: #a31515"&gt;&amp;quot;some string&amp;quot;&lt;/span&gt;;         &lt;br /&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;&amp;quot;some string&amp;quot;&lt;/span&gt;, (&lt;span style="color: blue"&gt;string&lt;/span&gt;)myFlow.MyString);         &lt;br /&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;&amp;quot;some string&amp;quot;&lt;/span&gt;, (&lt;span style="color: blue"&gt;string&lt;/span&gt;)myFlow.MyAction());         &lt;br /&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;&amp;quot;some other string&amp;quot;&lt;/span&gt;, (&lt;span style="color: blue"&gt;string&lt;/span&gt;)myFlow.MyAction(&lt;span style="color: #a31515"&gt;&amp;quot;some other string&amp;quot;&lt;/span&gt;));&lt;/span&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;For a complete listing search for ‘TjDlrTest.cs’ in the &lt;a href="http://jetfire.codeplex.com"&gt;codeplex download&lt;/a&gt;.&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;Also see      &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/test_06.html"&gt;Dynamic Method Call Simplifies C# Code&lt;/a&gt;&lt;/span&gt;     &lt;br /&gt;&lt;a href="http://wiki.jetfire.ca/Application%20Interface.ashx"&gt;Jetfire wiki article : Application Interface&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br style="mso-special-character: line-break" /&gt;    &lt;br style="mso-special-character: line-break" /&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-6723851362472878823?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/6723851362472878823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=6723851362472878823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6723851362472878823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6723851362472878823'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-objects-now-support-net-dlr.html' title='Jetfire objects now Support .net DLR'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-4859240208452593266</id><published>2010-06-16T09:40:00.001-04:00</published><updated>2010-07-12T08:27:21.932-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio 2010'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Multiple Line Lambda Expressions – New in Visual Studio 2010</title><content type='html'>&lt;p&gt;New is Visual Studio 2010 is the ability to write multiple line lambda Expressions.&amp;#160; The following example a lambda expression that is assigned to the delegate ‘MyFunc’.&lt;/p&gt;  &lt;p&gt;The type ‘&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;’ specifies to create a delegate (a method represented as an object) with a single ‘int’ parameter and return type of ‘bool’.&amp;#160; See &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/built-in-delegate-types-methods-as.html"&gt;Built-in Delegates&lt;/a&gt; type for more information on ‘&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;’. &lt;/p&gt;  &lt;p&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]       &lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Lambda_MultipleLines()       &lt;br /&gt;{       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt; MyFunc = i =&amp;gt;       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (i == 22) &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;true&lt;/span&gt;;       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;else&lt;/span&gt; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;;       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;};       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;bool&lt;/span&gt; flag = MyFunc(22);       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsTrue(flag);       &lt;br /&gt;      &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;flag = MyFunc(1);       &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsFalse(flag);       &lt;br /&gt;} &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;Also See:    &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/built-in-delegate-types-methods-as.html"&gt;Builtin Delegates - Methods as objects&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/test_06.html"&gt;Dynamic Method Call Simplifies C# 4.0 Code&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-4859240208452593266?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/4859240208452593266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=4859240208452593266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4859240208452593266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4859240208452593266'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/multiple-line-lambda-expressions-new-in.html' title='Multiple Line Lambda Expressions – New in Visual Studio 2010'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-7278652647558686708</id><published>2010-06-15T16:35:00.001-04:00</published><updated>2010-06-27T11:26:56.005-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Built-in Delegate Types - Methods as objects</title><content type='html'>&lt;table border="0" cellspacing="0" cellpadding="2" width="631"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="470"&gt;&amp;#160; A delegate in .net C# is merely a reference to a method that allows you to a) programmatically call a method, b) pass a method as a method parameter or c)store a method as a variable or in a collection.&amp;#160;&amp;#160; In short delegates allow methods to be used like an object.          &lt;br /&gt;          &lt;br /&gt;One of the issues with delegates is that declaration process is quite difficult.&amp;#160;&amp;#160; First declare a delegate type, then use the delegate type in a declaration.&amp;#160;&amp;#160; To make life simpler in C# there are 2 major built-in delegate types, ‘&lt;strong&gt;Action&lt;/strong&gt;’ and ‘&lt;strong&gt;Func&lt;/strong&gt;’ (Function).&amp;#160; These built-in types provide a shorthand notation that virtually eliminate the need to declare delegate types.&lt;/td&gt;        &lt;td valign="top" width="10" align="center"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="150" align="center"&gt;         &lt;p style="border-bottom: #000 1px solid; border-left: #000 1px solid; padding-bottom: 3px; margin: 1em 10px; padding-left: 3px; padding-right: 3px; border-top: #000 1px solid; border-right: #000 1px solid; padding-top: 5px"&gt;&lt;em&gt;&lt;strong&gt;Action&lt;/strong&gt; and &lt;strong&gt;Func&lt;/strong&gt; are really a shorthand notation&amp;#160; that virtually eliminate the need to declare delegate types in C#.&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;u&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/u&gt; &lt;em&gt;is a delegate type that describes a method that does not return a value&lt;/em&gt;.&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;table border="1" cellspacing="0" cellpadding="2" width="599"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="144"&gt;&lt;strong&gt;Built-in Delegate Type&lt;/strong&gt;&lt;/td&gt;          &lt;td valign="top" width="453"&gt;&lt;strong&gt;Describes:&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="144"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.action.aspx"&gt;Action&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="453"&gt;a method that does not return a value and has no parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="147"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx"&gt;Action&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="453"&gt;a method that does not return a value and has 1 parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="150"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549311.aspx"&gt;Action&amp;lt;T1, T2&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="453"&gt;a method that does not return a value and has 2 parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="152"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549392.aspx"&gt;Action&amp;lt;T1, T2, T3&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="453"&gt;a method that does not return a value and has 3 parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="154"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb548654.aspx"&gt;Action&amp;lt;T1, T2, T3, T4&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="453"&gt;a method that does not return a value and has 4 parameters.&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Func&lt;/u&gt;&lt;/strong&gt; &lt;em&gt;is a delegate type that describes a method that returns a value.&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;table border="1" cellspacing="0" cellpadding="2" width="596"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="196"&gt;&lt;strong&gt;Built-in Delegate Type&lt;/strong&gt;&lt;/td&gt;          &lt;td valign="top" width="399"&gt;&lt;strong&gt;Describes:&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="196"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx"&gt;Func&amp;lt;TResult&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="399"&gt;a method that returns a value and has no parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="196"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549151.aspx"&gt;Func&amp;lt;T, TResult&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="399"&gt;a method that returns a value and has 1 parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="196"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534647.aspx"&gt;Func&amp;lt;T1, T2, TResult&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="399"&gt;a method that returns a value and has 2 parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="196"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549430.aspx"&gt;Func&amp;lt;T1, T2, T3,TResult&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="399"&gt;a method that returns a value and has 3 parameters.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="196"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534303.aspx"&gt;Func&amp;lt;T1, T2, T3, T4,TResult&amp;gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="399"&gt;a method that returns a value and has 4 parameters.&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Action Example&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Use Action&amp;lt;T&amp;gt; to encapsulate the instance method ‘Operation’ into a delegate object called ‘MyAction’&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span style="line-height: 115%; font-family: consolas; color: blue; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;private&lt;/span&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0;         &lt;br /&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]         &lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ActionExample()         &lt;br /&gt;{         &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; MyAction = &lt;span style="color: blue"&gt;this&lt;/span&gt;.Operation;         &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;MyAction(33);         &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(34, i);         &lt;br /&gt;}         &lt;br /&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Operation(&lt;span style="color: blue"&gt;int&lt;/span&gt; x)         &lt;br /&gt;{         &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;i = x + 1; &lt;span style="color: green"&gt;// doesn't do much&lt;/span&gt;         &lt;br /&gt;}&lt;/span&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Func Example&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Use Func&amp;lt;T, TResult&amp;gt; to encapsulate an anonymous method (that has an integer parameter and returns an integer) into a delegate object called ‘MyFunc’&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span style="line-height: 115%; font-family: consolas; font-size: 9.5pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: consolas; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]         &lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; FuncExampleAnonymous()         &lt;br /&gt;{         &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; MyFunc = &lt;span style="color: blue"&gt;del&lt;a href="http://www.searchenginepeople.com/wp-content/uploads/2008/02/delegate-authority.jpg"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" title="click to enlarge" alt="click to enlarge" align="right" src="http://www.searchenginepeople.com/wp-content/uploads/2008/02/delegate-authority.jpg" width="235" height="229" /&gt;&lt;/a&gt;egate&lt;/span&gt;(&lt;span style="color: blue"&gt;int&lt;/span&gt; x) { &lt;span style="color: blue"&gt;return&lt;/span&gt; x + 1; };         &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;int&lt;/span&gt; z = MyFunc(33);         &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(34, z);         &lt;br /&gt;}         &lt;br style="mso-special-character: line-break" /&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Also See:    &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/multiple-line-lambda-expressions-new-in.html"&gt;Multiple line Lamda expressions - New Visual Studio 2010&lt;/a&gt;&amp;#160; &lt;br /&gt;    &lt;br /&gt; Further reading&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.switchonthecode.com/tutorials/csharp-tutorial-the-built-in-generic-delegate-declarations"&gt;C# Tutorial - The Built-In Generic Delegate Declarations&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc301810.aspx"&gt;An Introduction to Delegates&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-7278652647558686708?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/7278652647558686708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=7278652647558686708' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7278652647558686708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7278652647558686708'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/built-in-delegate-types-methods-as.html' title='Built-in Delegate Types - Methods as objects'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-9130427925141422506</id><published>2010-06-12T09:33:00.002-04:00</published><updated>2010-06-25T10:25:05.098-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Integrated ORM in Jetfire V1.2</title><content type='html'>&lt;br /&gt;  &lt;p&gt;New in .net &lt;a href="http://jetfire.ca/"&gt;Jetfire&lt;/a&gt; language &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WqqRGkoDIG0/TCSyjLBo90I/AAAAAAAAAB0/mE3ovJWCJLs/s1600/microsoft_sql_logo.png"&gt;&lt;img style="width: 136px; display: inline; height: 85px; margin-left: 0px; cursor: hand; margin-right: 0px" id="BLOGGER_PHOTO_ID_5486706563368941378" border="0" alt="" align="right" src="http://3.bp.blogspot.com/_WqqRGkoDIG0/TCSyjLBo90I/AAAAAAAAAB0/mE3ovJWCJLs/s320/microsoft_sql_logo.png" /&gt;&lt;/a&gt;version 1.2 is an integrated transparent &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;object relational mapping&lt;/a&gt; (ORM) system. The system is transparent to Jetfire programmer. The major benefit is that &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-v12-allows-applications-to-have.html"&gt;Jetfire now supports unlimited number of objects&lt;/a&gt;, constrained only by the database. Jetfire comes complete with drivers for SQL 2008 (including 2008 Express). Drivers for other database systems can easily be created if they support .net &lt;a href="http://en.wikipedia.org/wiki/Language_Integrated_Query"&gt;Linq&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Jetfire still contains its original &lt;a href="http://en.wikipedia.org/wiki/System_Prevalence"&gt;prevalence object persistence&lt;/a&gt; mechanism. This prevalence mechanism has been enhanced by an transparent ORM system.&lt;a href="http://www.funnytimes.com/archives/files/art/20091014.jpg"&gt;&lt;img style="margin: 0px 0px 0px 5px; display: inline" align="right" src="http://www.funnytimes.com/archives/files/art/20091014.jpg" width="162" height="190" /&gt;&lt;/a&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;In the Jetfire language when objects are created or changed they are automatically placed in the public workspace. All objects in the public workspace are automatically loaded on initialization. Objects can optionally be placed in workspaces where objects are only brought into main memory if they are explicitly needed or as the result of query operation.&lt;/p&gt;  &lt;p&gt;Linq style queries are directly supported in the Jetfire language. Queries can also be performed directly from .net C#. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://3.bp.blogspot.com/_WqqRGkoDIG0/TBObL1sOG_I/AAAAAAAAABI/aSKSotlgsKA/s1600/Ormmodel.jpg"&gt;&lt;img src="http://3.bp.blogspot.com/_WqqRGkoDIG0/TBObL1sOG_I/AAAAAAAAABI/aSKSotlgsKA/s1600/Ormmodel.jpg" width="611" height="458" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;See also   &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-object-persistence-is-tip-of.html"&gt;Persistence is the Tip of the Iceberg&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-9130427925141422506?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/9130427925141422506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=9130427925141422506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/9130427925141422506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/9130427925141422506'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/integrated-orm-in-jetfire-v12.html' title='Integrated ORM in Jetfire V1.2'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WqqRGkoDIG0/TCSyjLBo90I/AAAAAAAAAB0/mE3ovJWCJLs/s72-c/microsoft_sql_logo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-511192649775523245</id><published>2010-06-11T12:43:00.001-04:00</published><updated>2010-06-25T18:27:22.323-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><category scheme='http://www.blogger.com/atom/ns#' term='DLR'/><title type='text'>Build Large Applications with Jetfire KISS</title><content type='html'>&lt;br /&gt;  &lt;p&gt;&lt;a href="http://www.cartoonstock.com/newscartoons/cartoonists/mfl/lowres/mfln1683l.jpg"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://www.cartoonstock.com/newscartoons/cartoonists/mfl/lowres/mfln1683l.jpg" width="156" height="134" /&gt;&lt;/a&gt;A common mantra in software engineering is to keep the amount code small. This sometimes known simply as the &lt;a href="http://en.wikipedia.org/wiki/Keep_it_simple_stupid"&gt;Kiss principle&lt;/a&gt; (Keep it short and simple or Keep it Simple Stupid). The smaller and simpler the code the easier it is write, debug, verify correctness, comprehend, test and maintain an application. Smaller code sizes also mean that the application can be built faster. Although these benefits may come at a price of larger memory requirements and slower performance, this is a price that many will gladly pay, especially given today’s rapidly changing business environment, inexpensive memory and fast processors. &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="606"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="317"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px 0px 25px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" src="http://www.travelstoinsanity.com/wp-content/uploads/2009/02/stscpanel.jpg" width="286" height="189" /&gt;&lt;/td&gt;        &lt;td valign="top" width="287"&gt;&lt;em&gt;           &lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;Complex things consume resources&lt;/em&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;a href="http://jetfire.ca"&gt;&lt;img style="margin: 0px 15px 0px 0px; display: inline" align="left" src="http://jetfire.ca/Images/PoweredByJetfire.png" /&gt;&lt;/a&gt; Keeping it simple has been our main goal for the dynamic .net language &lt;a href="http://jetfire.ca/"&gt;Jetfire&lt;/a&gt;&amp;#160; since day one. We wanted a simple programming model that can anyone can easily build a large Web applications.&amp;#160; We believe we have been successful as we have built a number of applications with less than 1000 lines of Jetfire code, one example is the &lt;a href="http://oawa.ca/"&gt;OAWA&lt;/a&gt; registration system.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_WqqRGkoDIG0/TBJrunraaBI/AAAAAAAAAAU/gG20M7xueTw/s1600/oawaRegistration.jpg"&gt;&lt;img src="http://1.bp.blogspot.com/_WqqRGkoDIG0/TBJrunraaBI/AAAAAAAAAAU/gG20M7xueTw/s1600/oawaRegistration.jpg" width="601" height="338" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The OAWA registration system needs to keep track of thousands of athletes.&amp;#160; The athletes all belong to a local wrestling club as well as the provincial organization.&amp;#160;&amp;#160; Each local club registrar has only access to that club’s athletes; however the OAWA registrar has access to all athletes.&amp;#160; This entire system was built with less than 1,000 lines of Jetfire code.&amp;#160; Of those 1,000 lines of code over 90% is property definitions (eg defining variables such as FirstName, Club Name, etc.). &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="602"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://www.enhansoft.com/pages/products.aspx"&gt;&lt;img style="margin: 0px 20px 0px 0px; display: inline" align="left" src="http://www.enhansoft.com/Images/new_suite250x225.jpg" width="193" height="174" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="400"&gt;         &lt;p&gt;&amp;#160;&lt;/p&gt;          &lt;p&gt;The Enhansoft software registration application is an embedded application.&amp;#160; This Jetfire application is designed to track software usage of the &lt;a href="http://www.enhansoft.com/pages/products.aspx"&gt;ehansoft productivity suite&lt;/a&gt;.&amp;#160; The entire registration application is only 350 lines of code.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Our main criteria for simplicity when designing Jetfire has been the number of lines of code and can a “mere mortal” understand the program. The ‘mere mortal’ part has been important because it is possible to build code in languages that is terse; however it is virtually uncompressible, at least by a ‘mere mortal’.&amp;#160;&amp;#160; After all we are all ‘mere mortals’.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="576"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/VuXJyCmXYFfhgrD--sO1Ww"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="left" src="http://lh3.ggpht.com/_gy7YXPaEQI4/SqLujcH3BII/AAAAAAABkEo/UCSxznXoP2M/einstein.jpg" width="104" height="146" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="332"&gt;&lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Albert_Einstein"&gt;Einstein&lt;/a&gt;             &lt;br /&gt;“Make things as simple as possible, but not simpler”&lt;/em&gt;           &lt;p align="right"&gt;&amp;#160;&lt;/p&gt;          &lt;p align="right"&gt;&amp;#160;&lt;a href="http://en.wikipedia.org/wiki/Leonardo_Da_Vinci"&gt;Leonardo Da Vinci&lt;/a&gt;             &lt;br /&gt;&lt;em&gt;&amp;quot;Simplicity is the ultimate sophistication&amp;quot;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="109"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://2.bp.blogspot.com/_WqqRGkoDIG0/TBKGYVqQIxI/AAAAAAAAAAc/Oh7LVn5jik4/s1600/Lenardo.jpg" width="92" height="125" /&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Related Articles:   &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2009/03/why-domain-specific-language-is-better.html"&gt;Why a domain specific language is better than a framework.&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2009/04/modeling-workflow-in-software.html"&gt;Modelling a workflow in software&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-511192649775523245?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/511192649775523245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=511192649775523245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/511192649775523245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/511192649775523245'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/build-large-applications-with-kiss.html' title='Build Large Applications with Jetfire KISS'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_WqqRGkoDIG0/TBJrunraaBI/AAAAAAAAAAU/gG20M7xueTw/s72-c/oawaRegistration.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2173984358336411644</id><published>2010-06-08T19:28:00.001-04:00</published><updated>2010-06-25T15:33:29.635-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><category scheme='http://www.blogger.com/atom/ns#' term='linq to sql'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><title type='text'>Case Sensitive Linq to SQL Queries</title><content type='html'>&lt;p&gt;&lt;a href="http://www.fritzcartoons.com/wp-content/uploads/2008/11/case-sensitive-web.jpg"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://www.fritzcartoons.com/wp-content/uploads/2008/11/case-sensitive-web.jpg" width="223" height="231" /&gt;&lt;/a&gt;By default,&amp;#160; &lt;a href="http://en.wikipedia.org/wiki/Language_Integrated_Query"&gt;Linq to SQL&lt;/a&gt; queries are case insensitive.&amp;#160; The C# convention is that all comparisons are case sensitive.&amp;#160; This is a problem and begs the question ‘How to perform a case sensistive query using Linq to Sql’? &lt;/p&gt;  &lt;p&gt;To solve this problem declare ‘string’ fields of the linq-to-sql data class to be case sensitive by specifying the server data type by using one of the following;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;varchar(4000) COLLATE SQL_Latin1_General_CP1_CS_AS&lt;/font&gt;         &lt;br /&gt;&lt;/strong&gt;or       &lt;br /&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;nvarchar(Max) COLLATE SQL_Latin1_General_CP1_CS_AS&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Note: The ‘CS’ in the above collation types means ‘Case Sensitive’.&lt;/p&gt;  &lt;p&gt;This can be entered in the “Server Data Type” field when viewing a property using Visual Studio DBML Designer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.trackerrealm.com/blogimages/caseSensitive.jpg"&gt;&lt;img src="http://www.trackerrealm.com/blogimages/caseSensitive.jpg" width="406" height="256" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cartoonstock.com/newscartoons/cartoonists/rro/lowres/rron794l.jpg"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="left" src="http://www.cartoonstock.com/newscartoons/cartoonists/rro/lowres/rron794l.jpg" width="109" height="104" /&gt;&lt;/a&gt; The following code demonstrates how to perform both case insensitive and case sensitive queries.&amp;#160; First set the ‘Server Data Type’ as shown above.&amp;#160;&amp;#160; The code creates 2 Contact objects (database records) with the ‘Name’ field set to ‘Bob’ and ‘bob’.&amp;#160; Performing a case sensitive query returns 1 ‘Contact’ object and performing a case insensitive search returns 2 ‘Contact’ objects.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote style="background: #efeff7"&gt;   &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; color: blue; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;using&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt; (&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 10pt; mso-no-proof: yes"&gt;SciProjectTestDataContext&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt; dc = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SciProjectTestDataContext&lt;/span&gt;(         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #a31515"&gt;@&amp;quot;Data Source=Blackoak\SQLEXPRESS2008;AttachDbFilename=C:\DbSciProjectTest.mdf;Integrated Security=True&amp;quot;&lt;/span&gt;))        &lt;br /&gt;{        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; if&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt; (dc.DatabaseExists())        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;dc.DeleteDatabase();         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; dc.CreateDatabase();        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; Table&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt;&amp;gt; contact = dc.GetTable&amp;lt;&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt;&amp;gt;();         &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="font-family: &amp;#39;Courier New&amp;#39;; color: green; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; //        &lt;br /&gt;&amp;#160;&amp;#160; // Create ‘Contact’ records in the database         &lt;br /&gt;&amp;#160;&amp;#160; //&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; Contact&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt; c1 = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Contact          &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; {        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;Name = &lt;span style="color: #a31515"&gt;&amp;quot;Bob&amp;quot;          &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; };        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; dc.Contacts.InsertOnSubmit(c1);        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; Contact&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt; c2 = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Contact          &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; {        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;Name = &lt;span style="color: #a31515"&gt;&amp;quot;bob&amp;quot;          &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; };        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; dc.Contacts.InsertOnSubmit(c2);        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; dc.SubmitChanges();        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: green; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; //        &lt;br /&gt;&amp;#160;&amp;#160; // Case sensitive query         &lt;br /&gt;&amp;#160;&amp;#160; //&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: green; font-size: 10pt; mso-no-proof: yes"&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; Contact&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;[] cArray = dc.Contacts.Where(c =&amp;gt; c.Name == &lt;span style="color: #a31515"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt;).ToArray();         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; Assert&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;.AreEqual(1, cArray.Length);        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: green; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; //        &lt;br /&gt;&amp;#160;&amp;#160; // Case insensitive query         &lt;br /&gt;&amp;#160;&amp;#160; //         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes"&gt;&amp;#160;&amp;#160; cArray = dc.Contacts.Where(c =&amp;gt; c.Name.ToLower() == &lt;span style="color: #a31515"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt;).ToArray();         &lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 10pt; mso-no-proof: yes; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;&amp;#160;&amp;#160; Assert&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; mso-no-proof: yes; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-ca; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;.AreEqual(2, cArray.Length);&lt;/span&gt;       &lt;br /&gt;}      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;See Also:   &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/tips-to-prevent-net-memory-leaks.html"&gt;Tips to prevent memory leaks.&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2173984358336411644?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2173984358336411644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2173984358336411644' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2173984358336411644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2173984358336411644'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html' title='Case Sensitive Linq to SQL Queries'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-4440872572599712478</id><published>2010-06-06T18:10:00.001-04:00</published><updated>2010-09-03T09:09:25.152-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic Object'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='DLR'/><title type='text'>Dynamic Method Call Simplifies C# Code</title><content type='html'>&lt;p&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" align="left" src="http://www.trackerrealm.com/blogimages/c4.png" width="125" height="72" /&gt; How many times has this happened to you? You want to write &lt;a href="http://en.wikipedia.org/wiki/Elegance"&gt;elegant code&lt;/a&gt;, but you can’t since C# requires knowledge of the object types at compile time. This forces you to write code that determines the type of an object so that the correct overloaded method can be called. You have no choice so you end up with some pretty ugly code.&lt;/p&gt;  &lt;blockquote style="background: #efeff7"&gt;   &lt;p style="margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; color: blue; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;string&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt; s;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; color: green; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;//Assume either an 'int' or 'string' object&amp;#160; &lt;br /&gt;//is returned from GetObject&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; color: blue; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;object&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt; o = GetObject();        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; color: blue; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;if&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt; (o &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;string&lt;/span&gt;)         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;s = MyMethod((&lt;span style="color: blue"&gt;string&lt;/span&gt;)o);         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; color: blue; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;else&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;        &lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;s = MyMethod((&lt;span style="color: blue"&gt;int&lt;/span&gt;)o); &lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The overloaded ‘MyMethod’ for this example is quite simple.&lt;/p&gt;  &lt;blockquote style="background: #efeff7"&gt;   &lt;p style="margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; color: blue; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;public&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; MyMethod(&lt;span style="color: blue"&gt;int&lt;/span&gt; i)         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;{        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;#160;&amp;#160; return&lt;/span&gt; &lt;span style="color: #a31515"&gt;&amp;quot;int overload called.&amp;quot;&lt;/span&gt;;         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;}        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; MyMethod(&lt;span style="color: blue"&gt;string&lt;/span&gt; s)         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;{        &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;#160;&amp;#160; return&lt;/span&gt; &lt;span style="color: #a31515"&gt;&amp;quot;string overload called.&amp;quot;&lt;/span&gt;;         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;} &lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p style="margin: 0cm 0cm 0pt 63pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;/span&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;  &lt;p&gt;With Visual Studio 2010 and C# 4.0 you can now write elegant code (in this situation at least).&lt;/p&gt;  &lt;blockquote style="background: #efeff7"&gt;   &lt;p style="margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; o = GetObject();         &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: consolas; font-size: 9.5pt; mso-bidi-font-family: consolas"&gt;&lt;span style="color: blue"&gt;string&lt;/span&gt; s = MyMethod(o); &lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="637"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="409"&gt;         &lt;p&gt;This is much more elegant. It works because now the type of the object 'o' is determined at runtime and the correct overloaded method is called at runtime. In effect, the underlying code is the same, but now the compiler generates this code.&lt;/p&gt;          &lt;p&gt;So if you find yourself generating code where you are testing the type of an object, then chances are that it can be simplified by using the dynamic type in C# 4.0.&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="226"&gt;         &lt;p style="border-bottom: #000 1px solid; border-left: #000 1px solid; padding-bottom: 5px; margin: 1em 20px; padding-left: 5px; padding-right: 5px; border-top: #000 1px solid; border-right: #000 1px solid; padding-top: 5px"&gt;&lt;em&gt;             &lt;br /&gt;“Elegance is not a dispensable luxury but a quality that decides between success and failure.”               &lt;br /&gt;&lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Edsger_W._Dijkstra"&gt;Edsger W. Dijkstra&lt;/a&gt;             &lt;br /&gt;            &lt;br /&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Also See:    &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/multiple-line-lambda-expressions-new-in.html"&gt;Multiple Lambda Expressions in C# 4.0&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Further Reading:    &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/C_Sharp_4.0"&gt;Wikipedia C# 4.0&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/ff796223.aspx"&gt;MSDN article&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Multimethods"&gt;Wikipedia Multiple Dispatch&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-4440872572599712478?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/4440872572599712478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=4440872572599712478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4440872572599712478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4440872572599712478'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/test_06.html' title='Dynamic Method Call Simplifies C# Code'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-1823760417842449382</id><published>2010-06-04T12:10:00.001-04:00</published><updated>2010-06-29T09:06:16.932-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><category scheme='http://www.blogger.com/atom/ns#' term='DLR'/><title type='text'>Jetfire V1.2 Allows Applications to have an Unlimited Number of Objects</title><content type='html'>&lt;span xmlns="xmlns"&gt;   &lt;table border="0" cellspacing="0" cellpadding="2" width="641"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="138"&gt;&lt;img alt="" align="left" src="http://www.trackerrealm.com/blogimages/magnify.png" width="129" height="130" /&gt;&lt;/td&gt;          &lt;td valign="top" width="501"&gt;New in release V1.2 of the dynamic language &lt;a href="http://jetfire.ca"&gt;Jetfire&lt;/a&gt; is object oriented database searching (integrated &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/integrated-orm-in-jetfire-v12.html"&gt;ORM),&lt;/a&gt; support for object references to non-cached objects and partially cached '&lt;a href="http://wiki.jetfire.ca/Workspace.ashx"&gt;Workspaces&lt;/a&gt;'. These features allow applications to be built that contain an almost unlimited number of objects, constrained only by the size of the database. An example is a marathon registration system that was required to handle 100,000+ athletes. &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;table border="0" cellspacing="0" cellpadding="2" width="641"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="355"&gt;           &lt;p&gt;Previous to V1.2 all objects were loaded every time a Jetfire application started. This provides for fast access since all objects are in memory and is great for many applications where number of objects is less than 10k to 100k. Many systems successfully use this technique. When the application has millions of objects this technique breaks down due to the time it takes to load all the objects into memory and the amount of memory required. &lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="284"&gt;           &lt;p style="border-bottom: #000 1px solid; border-left: #000 1px solid; padding-bottom: 5px; margin: 1em 20px; padding-left: 5px; padding-right: 5px; border-top: #000 1px solid; border-right: #000 1px solid; padding-top: 5px"&gt;&lt;a href="http://jetfire.ca"&gt;Jetfire&lt;/a&gt; is designed to be simple enough for power users,               &lt;br /&gt;but capable enough for programmers.&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;table border="0" cellspacing="0" cellpadding="2" width="642"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="488"&gt;Now a .net Jetfire application &lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/marthon-jetfire-application-example.html"&gt;(Marathon example)&lt;/a&gt; can choose to only cache a few objects on start up. Then the application can perform a search using a full object oriented &amp;quot;where&amp;quot; expression. In our marathon registration example a specific athlete, state, province or sports club could be the parameter of the search. This will automatically cache the found objects in memory. Should any of the Jetfire objects contain references to non-cached objects these will be transparently cached into memory as required. If an athlete object had a property that referenced their local marathon running club, then the club object would be transparently cached should the software use that club property. &lt;/td&gt;          &lt;td valign="top" width="152"&gt;&lt;a href="http://www.flickr.com/photos/36665622@N00/253527065/"&gt;&lt;img alt="" align="right" src="http://www.trackerrealm.com/blogimages/060410_1610_JetfireV12A2.jpg" width="419" height="314" /&gt;&lt;/a&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;blockquote&gt;     &lt;p style="border-bottom: #000 1px solid; border-left: #000 1px solid; padding-bottom: 5px; margin: 1em 20px; padding-left: 5px; padding-right: 5px; border-top: #000 1px solid; border-right: #000 1px solid; padding-top: 5px"&gt;Jetfire is a .net open source, object oriented ecosystem designed to make writing persistent programs, workflows and policy management rules, very easy. The Jetfire language extends the C#&amp;#160; programming model with integrated object oriented database functions (&lt;a href="http://en.wikipedia.org/wiki/Object-relational_"&gt;ORM&lt;/a&gt;), &lt;a href="http://wiki.jetfire.ca/Role.ashx"&gt;roles&lt;/a&gt; (integrated security), integrated source control, states (workflow) and dynamic typing.&amp;#160; For more details see &lt;a href="http://wiki.jetfire.ca/First%20Class%20Constructs.ashx"&gt;Jetfire first class constructs&lt;/a&gt;.&lt;/p&gt;   &lt;/blockquote&gt;    &lt;p&gt;&lt;font size="1"&gt;Marathon photo by &lt;/font&gt;&lt;a href="http://www.flickr.com/photos/36665622@N00/253527065/"&gt;&lt;font size="1"&gt;Martineric&lt;/font&gt;&lt;/a&gt;       &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;See also:      &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/marthon-jetfire-application-example.html"&gt;Marathon Example&lt;/a&gt;       &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-object-persistence-is-tip-of.html"&gt;Persistence is the Tip of the Iceberg&lt;/a&gt;       &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-objects-now-support-net-dlr.html"&gt;Jetfire objects support .net DLR&lt;/a&gt;&lt;/p&gt; &lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-1823760417842449382?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/1823760417842449382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=1823760417842449382' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1823760417842449382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1823760417842449382'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-v12-allows-applications-to-have.html' title='Jetfire V1.2 Allows Applications to have an Unlimited Number of Objects'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-6770246745324102000</id><published>2010-06-02T15:49:00.001-04:00</published><updated>2010-06-27T11:13:16.204-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Jetfire Object Persistence is the Tip of the Iceberg</title><content type='html'>&lt;span xmlns="xmlns"&gt;   &lt;p&gt;&lt;img style="margin: 0px 10px 0px 0px" alt="" align="left" src="http://www.trackerrealm.com/blogimages/060210_1949_JetfireObje1.jpg" /&gt;Imagine writing code without worrying about how to store and retrieve objects. We did. We have written a large amount code using .net ADO, isolated storage, XML storage and other methods. We tried almost everything that was available in dot net. The techniques we didn't try we evaluated, such as DB4O and Entity Framework. They all worked or could be made to work, but none these approaches were transparent. These approaches to persistence also required a significant amount of support code and lot of understanding by the programmer to make them operational.       &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;Transparent object persistence was one of the motivations for creating the Jetfire language (&lt;a href="http://wiki.jetfire.ca/First%20Class%20Constructs.ashx"&gt;other language motivations&lt;/a&gt;). We didn't want the application programmer to have to understand the underlying persistence framework. For example the following line of Jetfire code automatically stores the object 'myObj' in persistent storage, typically a SQL database.       &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="font-family: times new roman"&gt;// create an object        &lt;br /&gt;MyObject myObj = new MyObject();         &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;While adding persistence traditional OO benefits, as can be found in Java or C#, such as garbage collection, have been retained. For example if there is no reference to a Jetfire object, the garbage collector reclaims the object.      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;This; however is all the tip of the Jetfire persistence iceberg. Intrinsic to Jetfire is the concept of a user. All code must be executed by a user, even if it is just the default user (called Guest). Also multiple users can simultaneously execute code either on the same computer or multiple computers. All this places extra requirements on Jetfire persistence.      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;Jetfire object persistence has the following features:      &lt;br /&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Transparent to the programmer.        &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;All object operations and updates are atomic.        &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;Code (classes) as well as Jetfire objects are persisted.        &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;Built-in versioning for code(classes) supports upgrading of objects to the latest version of code.        &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;Audit objects are created for all transactions.        &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;       &lt;div&gt;Individual objects have access rights, not unlike files a multi-user file system.          &lt;br /&gt;&lt;/div&gt;        &lt;ul&gt;         &lt;li&gt;Objects can be assigned a role(s) restricting access to users that also have that same role assigned.            &lt;br /&gt;&lt;/li&gt;       &lt;/ul&gt;     &lt;/li&gt;      &lt;li&gt;Objects can be placed in a directory structure, using Workspaces. Workspaces are directories for objects providing an organizational structure and access rights.        &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;Searching for objects is supported. Searches can be performed using any field or property in the 'where' expression.        &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;By providing these features Jetfire relieves the application programmer of a huge programming effort allowing solutions to be delivered quickly.      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;Links      &lt;br /&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://wiki.jetfire.ca/Workflow.ashx"&gt;Workflow (Jetfire wiki)&lt;/a&gt;         &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;Related Articles &lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://trackerrealm.com/blogs/2009/04/modeling-workflow-in-software.html"&gt;Modeling a Workflow in Software&lt;/a&gt;         &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://trackerrealm.com/blogs/2009/03/what-domain.html"&gt;&lt;span style="font-family: trebuchet ms; font-size: 9pt"&gt;Writing Jetfire programs&lt;/span&gt;&lt;/a&gt;         &lt;br /&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2009/03/why-domain-specific-language-is-better.html"&gt;Why a domain specific language is better than a framework.&lt;/a&gt;         &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;     &lt;br /&gt;&amp;#160;&lt;/p&gt; &lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-6770246745324102000?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/6770246745324102000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=6770246745324102000' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6770246745324102000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6770246745324102000'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/06/jetfire-object-persistence-is-tip-of.html' title='Jetfire Object Persistence is the Tip of the Iceberg'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8725972937420638975</id><published>2010-03-29T09:44:00.001-04:00</published><updated>2010-03-29T09:50:25.680-04:00</updated><title type='text'>This blog has moved</title><content type='html'>&lt;br /&gt;       This blog is now located at http://yourdotnetdesignteam.blogspot.com/.&lt;br /&gt;       You will be automatically redirected in 30 seconds, or you may click &lt;a href='http://yourdotnetdesignteam.blogspot.com/'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;       For feed subscribers, please update your feed subscriptions to&lt;br /&gt;       http://yourdotnetdesignteam.blogspot.com/feeds/posts/default.&lt;br /&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8725972937420638975?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://yourdotnetdesignteam.blogspot.com/' title='This blog has moved'/><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8725972937420638975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8725972937420638975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8725972937420638975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8725972937420638975'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2010/03/this-blog-has-moved.html' title='This blog has moved'/><author><name>Blogs TrackerRealm</name><uri>http://www.blogger.com/profile/00331907846645255860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-1086593195292194594</id><published>2009-11-18T15:50:00.001-05:00</published><updated>2009-11-18T15:50:23.409-05:00</updated><title type='text'>ODNC Luncheon Seminar Series Presents: Test Driven Design (aRealWorldExample)</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;The &lt;a href='http://www.ottawacommunity.com'&gt;Ottawa .NET Community&lt;/a&gt; is please to invite you to a luncheon presentation on "Test Driven Design (aRealWorldExample)".  Test Driven Design is a powerful development paradigm and there's nothing like a simple "Real World Example" to help you wrap your head around it. The presentation is scheduled for Wednesday, November 18, 2009 at 12:00 noon. Bring your lunch and see how you can use Test Driven Design in your next project. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Test Driven Design (aRealWorldExample)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This session illustrates Test Driven Design in light of a real world scenario. The scenario involves a legacy class object that needs to be upgraded to meet a new user requirement. You will be walked through the process of creating the test cases that will be used to insure that the user requirement is fully met.  You will then see how the solution is developed around these test cases. Note that LINQ functionality will be included in the solution and you will have the added benefit of seeing this technology in action. At the end of this session you will have a better understanding of how to integrate Test Driven Design (and LINQ) into your next project. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;About Charles Wiebe&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Charles Wiebe is the co-founder of TrackerRealm, a company that specializes in workflow design.  He is a Microsoft .NET software architect/designer for Windows Forms and ASP.NET solutions. Charles' expertise lies in the Application Layer, working with Web Parts, and GUI development. He is currently responsible for the User Interface components used in COR, a Content Management System and Jetfire, a workflow domain specific language. Charles is an active member of Ottawa .Net Community; he has coordinated the last 2 Ottawa Code Camps and has played a major role in several ODNC Study Groups. Charles will also be one of the presenters at this year's Microsoft Tech Days Tour taking place in Ottawa next month.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='text-decoration:underline'&gt;                                            &lt;/span&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;The &lt;a href='http://jetfire.ca/Downloads/Source/ODNC%20Demo%20Nov%2009.zip'&gt;zip file&lt;/a&gt; contains the Visual Studio 2008 solution and PowerPoint used in the presentation.  &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Presentation covers:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The objective of upgrading the legacy filter class is to migrate the 'prototype' design done in 2007 and meeting with increasing success in market to a mass deployed component.  This means expanding the boundary conditions and improving the test methodology.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Test Driven Development shows how to create a test case, followed by writing the code to "make the test pass".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The legacy Filter class is upgraded to use Generic FindAll and Find methods with anonymous methods&lt;br /&gt;&lt;/li&gt;&lt;li&gt;New method is added to Filter class as an extension method – good technique to follow when you want to add code in sand-box and test before submitting to release stream.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Rhino.Mocks used to improve testing methodology.&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-1086593195292194594?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/1086593195292194594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=1086593195292194594' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1086593195292194594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1086593195292194594'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2009/11/odnc-luncheon-seminar-series-presents.html' title='ODNC Luncheon Seminar Series Presents: Test Driven Design (aRealWorldExample)'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-1270963699750175722</id><published>2009-04-29T16:22:00.001-04:00</published><updated>2010-06-11T20:22:03.060-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Jetfire – Maybe we should have called it DC#</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;We were joking around the other day trying to describe Jetfire when we hit upon DC#, for &lt;a href='http://en.wikipedia.org/wiki/Dynamic_programming_language'&gt;dynamic&lt;/a&gt; C#.   Now to be fair C# does have dynamic attributes (especially &lt;a href='http://en.wikipedia.org/wiki/C_Sharp_(programming_language)'&gt;C# 4.0&lt;/a&gt;); however most of C# functionality is determined at compile time.   Generally to be considered a dynamic language such as &lt;a href='http://en.wikipedia.org/wiki/Ironruby'&gt;IronRuby&lt;/a&gt;, or &lt;a href='http://en.wikipedia.org/wiki/Iron_Python'&gt;IronPython&lt;/a&gt;, most of a language's functionality should be determined at run time.   Dynamic languages do sacrifice some performance for increased application flexibility, although some would argue that in real applications there is no sacrifice in performance.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;We say Jetfire, at least in jest, should be called DC# because its syntax comes &lt;a href='http://wiki.jetfire.ca/Jetfire%20vs%20net%20CSharp.ashx'&gt;directly from C#&lt;/a&gt; and it is a dynamic language.   Jetfire has the following dynamic attributes&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Dynamic_typing'&gt;Dynamic typing&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://wiki.jetfire.ca/dynamic%20access%20modifier.ashx'&gt;Dynamic Access Modifiers&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;Code can be created and executed 'on the fly' &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Jetfire Links&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.jetfire.ca/'&gt;Jetfire Site&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://jetfire.codeplex.com/'&gt;Download Jetfire&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://wiki.jetfire.ca'&gt;Jetfire Technical wiki&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Related Articles&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2009/04/modeling-workflow-in-software.html'&gt;Modeling a Workflow in Software&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2009/03/what-domain.html'&gt;Writing Jetfire programs&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2009/03/why-domain-specific-language-is-better.html'&gt;Why use a Language vs a Framework&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2007/03/what-is-workflow-ecosystem_16.html'&gt;Workflow Ecosystem&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2007/09/auto-display-for-workflows.html'&gt;Displaying Workflows&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-1270963699750175722?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/1270963699750175722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=1270963699750175722' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1270963699750175722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1270963699750175722'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2009/04/jetfire-maybe-we-should-have-called-it.html' title='Jetfire – Maybe we should have called it DC#'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-4954872586449857041</id><published>2009-04-17T12:10:00.001-04:00</published><updated>2010-06-11T20:21:41.894-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Modeling a Workflow in Software</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;On the surface modeling a workflow in software might seem like a very straight forward task.   &lt;br /&gt;&lt;/p&gt;&lt;p&gt;After all according to &lt;a href='http://en.wikipedia.org/wiki/Workflow'&gt;wikipedia&lt;/a&gt; "&lt;em&gt;A &lt;strong&gt;workflow&lt;/strong&gt; is a depiction of a sequence of operations…".   &lt;/em&gt;This sounds like a great match for a computer program modeling the workflow.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You could then use the software workflow to &lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Guide you through the workflow process.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Perform actions through the software such as send email, operate equipment or perform a computational process such as adjust a photograph. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Facilitate approvals &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Record activity especially when actions were taken.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Roll up the results and status in other documents&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;However there are issues (you didn't think it could be quite this simple).    All of these issues are resolvable, but add an extra layer complexity to modeling a workflow in software.&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt; Workflow programs must be able to operate for days, weeks or even years.  The implication is that the workflow program must automatically preserve its status.  The status must be automatically restored if the computer is restarted.   &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Workflows go through states when the operations occur.   Operations, or commands, need to work only in the appropriate state.   For example a "Complete" command may only valid once the workflow is 'started'.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Workflows are performed by more than one person.  This means that the workflow must be able to support simultaneous users working on different computers or devices.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Workflows need to be shared, but also be protected from incorrect usage.   For an expense workflow the user may need to be a manager to approve it.   The workflow program needs support different roles for different users.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Not everyone who uses a workflow sees the same data.  For example an approver's comments may need to be hidden from the applicant.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Workflows change over time.  For example an 'approval' process may change while there are requests in the system.   The workflow software must be able to handle 'grandfathering' the process for requests already in the system or optionally support upgrading them.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Workflow programs need to be simple to design and build.   &lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This is rational behind the &lt;a href='http://en.wikipedia.org/wiki/Dynamic_programming_language'&gt;dynamic language&lt;/a&gt;&lt;br /&gt;				&lt;a href='http://www.jetfire.ca/'&gt;Jetfire&lt;/a&gt;.   Jetfire is &lt;a href='http://en.wikipedia.org/wiki/Domain_Specific_Language'&gt;domain specific language&lt;/a&gt; that handles all these issues with ease.  Applications can be built quickly.  Application code isn't obscured by reams of infrastructure code.   With Jetfire the designer of workflow software can concentrate on the application, not the infrastructure.  All this makes the workflow program more reliable and much easier to maintain.  &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Links&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.jetfire.ca/'&gt;Jetfire Site&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://jetfire.codeplex.com/'&gt;Download Jetfire&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://wiki.jetfire.ca'&gt;Jetfire Technical wiki&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Related Articles&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2009/03/what-domain.html'&gt;Writing Jetfire programs&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2009/03/why-domain-specific-language-is-better.html'&gt;Why use a Language vs a Framework&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2007/03/what-is-workflow-ecosystem_16.html'&gt;Workflow Ecosystem&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;li&gt;&lt;a href='http://trackerrealm.com/blogs/2007/09/auto-display-for-workflows.html'&gt;Displaying Workflows&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-4954872586449857041?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/4954872586449857041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=4954872586449857041' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4954872586449857041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4954872586449857041'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2009/04/modeling-workflow-in-software.html' title='Modeling a Workflow in Software'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-4581170875670356113</id><published>2009-03-22T10:53:00.001-04:00</published><updated>2009-03-24T09:23:47.286-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Form Maker debut</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;We have been asked a number of times "where is the Jetfire visual designer"?  Our attention was aimed at getting the programmatic model correct.  We are now starting to deliver purpose-built visual designers.  Why multiple designers?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The objective of Jetfire visual designers is to:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Provide simple GUI's for building applications&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Take the 'programming' out of 'application programming'&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Easily deploy applications&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Provide a one-step process to writing and deploying applications&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img alt='' src='http://TrackerRealm.com/BlogImages/032209_1453_FormMakerde1.png'/&gt;Figure 1: Form Maker in design mode&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Our first release for purpose-built visual designers includes &lt;a href='http://wiki.jetfire.ca/Form%20Maker.ashx'&gt;Form Maker&lt;/a&gt;.  It is a simple first step, but designed to be practical.  The key features of Form Maker include:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Add one or more properties&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reorder properties&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Identify the property type (text, date, duration, integer, and more)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Build applications based on previous programs&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Form validation&lt;br /&gt;&lt;/li&gt;&lt;li&gt;One-click deployment&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img alt='' src='http://TrackerRealm.com/BlogImages/032209_1453_FormMakerde2.png'/&gt;Figure 2: Form Maker in layout mode &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Click the 'Show Form Layout' link and Form Maker displays how the Form is displayed to a user.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The differentiator of Form Maker is one-click deployment.  The user creates an application and with one click adds the application to the Jetfire ecosystem – ready for use.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://TrackerRealm.com/BlogImages/032209_1453_FormMakerde3.png' align='left'/&gt;Figure 3: Property types&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Figure 3 shows the types of properties that can be added to a form in Release 1.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;'UnknownType is displayed when reviewing an existing program and the property type is unknown, e.g. an enumeration.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-4581170875670356113?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/4581170875670356113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=4581170875670356113' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4581170875670356113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4581170875670356113'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2009/03/form-maker-debut.html' title='Form Maker debut'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2224540894961763661</id><published>2009-03-22T10:51:00.001-04:00</published><updated>2009-03-24T09:23:47.286-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Supporting Quality Processes</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;In a &lt;a href='http://trackerrealm.com/blogs/2007_09_01_archive.html'&gt;previous blog&lt;/a&gt;, we stated that the "objective of Jetfire &lt;span style='color:black; font-family:Trebuchet MS; font-size:9pt'&gt;is to simplify the workflow creation/modification process so that Power Users can build workflows and upgrade them".&lt;/span&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;In the early 90's, I worked for a large corporation that implemented ISO-9001.  To be compliant with ISO-9001, each department has to show that they followed their processes.  The easiest process to show compliance was the software submission process, because it was tooled.  Tracking the paper processes required continuous manual intervention.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Continuous Improvement is the name of the game to improve product quality.  Software that naturally reinforces the rules is required to support quality processes.  Tooling with the ability to easily upgrade is required.  With this back-drop, let's look at Jetfire.&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;New Jetfire workflows are easily added, without &lt;a href='http://en.wikipedia.org/wiki/Upgrade'&gt;upgrading&lt;/a&gt; system software.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Jetfire workflows should easily up-version.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Light-weight &lt;a href='http://www.trackerrealm.com/Blogs/Workflow/Attributes%20of%20a%20Complete%20Workflow%20Eco.htm'&gt;workflow ecosystem&lt;/a&gt;&lt;br /&gt;				&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Jetfire programs are built on an object oriented ecosystem that executes Jetfire code interpretively.  This approach allows Jetfire workflows to be easily uploaded, without the need to upgrade the system software.  &lt;br /&gt;&lt;/p&gt;&lt;p&gt;To up-version code, version is included in every object in the system.  New code creates a new version of a Workflow Class, which are related to previous versions of the named workflow class. New and previous versions of the Workflow Class are accessible with the preferred class to be instantiated being the current version.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Finally, the small size of the Jetfire ecosystem provides a compact environment that is targeted at building applications.  &lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2224540894961763661?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2224540894961763661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2224540894961763661' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2224540894961763661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2224540894961763661'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2009/03/why-scripting-language.html' title='Supporting Quality Processes'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-6664412275562692597</id><published>2009-03-22T10:33:00.001-04:00</published><updated>2009-03-24T09:23:47.286-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Writing programs for the workflow domain</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Jetfire is a DSL (domain specific language).  So what domain are we talking about?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;When we started Jetfire, the goal was to create a language that makes &lt;a href='http://en.wikipedia.org/wiki/workflow'&gt;workflows&lt;/a&gt; easy to write. I can say without reservation that we have achieved that goal.  Let's review the differences between Jetfire and C#.&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Jetfire is based on C#, so that programmers can easily write it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The keyword 'workflow' replaces 'class'.  'workflow' is used to activate first class support for workflow constructs.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Dynamic Access Modifiers are used to make class members public/private depending on who is using the class.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The Jetfire domain specific language incorporates first class support for workflow constructs.    &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Let's review some examples of how Jetfire simplifies writing workflows.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Example 1: States – Some workflows are &lt;a href='http://wiki.jetfire.ca/states.ashx'&gt;state driven&lt;/a&gt;. Jetfire Methods include a new type of method: the state method.  'enterstate' is a keyword used to promote the workflow into the specified state.&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse'&gt;&lt;colgroup&gt;&lt;col style='width:638px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;public workflow MyFlow &lt;br/&gt;{ &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    // 'Start' state&lt;/span&gt;&lt;span style='font-family:Times New Roman; font-size:12pt'&gt;&lt;br /&gt;									&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    Start() &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    { &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;        // place code to be executed when the state is entered. &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    } &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    // constructor &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    public MyFlow() &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;        // put the workflow into the Start state&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;        enterstate Start() &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    } &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Example 2: Dynamic Access Modifier example using states – the AddData method is public when the workflow is in the Start state.  Otherwise, the AddData method is private.&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse'&gt;&lt;colgroup&gt;&lt;col style='width:638px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;private ArrayList dataList = new ArrayList();&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;// method 'AddData' has a dynamic access modifier&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;public void AddData(string data) : states(Start) &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;{ &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    this.dataList.Add(data);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Example 3: Dynamic Access Modifier example using &lt;a href='http://wiki.jetfire.ca/Access%20Construct.ashx'&gt;access&lt;/a&gt; – the DoSomething method is public if the logged in user has the Role 'Approver'.  Otherwise, the DoSomething method is private. &lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse'&gt;&lt;colgroup&gt;&lt;col style='width:638px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;public void DoSomething() : access("Approver")&lt;br/&gt;{ &lt;br/&gt;    ...&lt;br/&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;These are some powerful examples how a domain specific language can simplify writing workflows.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-6664412275562692597?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/6664412275562692597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=6664412275562692597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6664412275562692597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6664412275562692597'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2009/03/what-domain.html' title='Writing programs for the workflow domain'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8758015768402269586</id><published>2009-03-17T14:20:00.001-04:00</published><updated>2010-06-11T20:16:33.942-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Why a Domain Specific Language is better than a Framework!</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;If you are a programmer you use frameworks.  Some frameworks such as a collection framework are almost indistinguishable from the language.  I know in my C# code I find almost all my classes contain either 'List' or 'Dictionary'.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Other frameworks such as &lt;a href='http://en.wikipedia.org/wiki/ADO.NET'&gt;ADO .net&lt;/a&gt; are very large and require quite a bit of time learn.   They provide an indispensible service to your application but are very difficult to learn and use.    The application code that employs the framework is almost unintelligible.  Adding more comments or the more judicious use of variable names seems to have no effect on making the code look better.   The problem is that most frameworks need to expose details of internal concepts to application as numerous tunable parameters and properties.  This is required since a typical framework has no other mechanism of inferring intent.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The need for the framework to have numerous tunable parameters and properties (lazy loading, concurrency issues, etc) compounds usage problems.  This is because in order to be used correctly they need to be understood.   Subtle errors in understanding a concept of a framework produces either subtle errors in the application or causes the application not to run a peak performance.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Using a &lt;a href='http://en.wikipedia.org/wiki/Domain-specific_language'&gt;domain specific language&lt;/a&gt; addresses a number of these problems.&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A domain specific language after all is just another language.   Most languages can be learned in a few hours to a few days.   When we wrote &lt;a href='http://jetfire.ca/'&gt;Jetfire&lt;/a&gt; we started with C# syntax adding few specific features.   A programmer's investment in understanding languages could be reused.   The additional features in Jetfire, for example, are consistent with the C# programming paradigm.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The code in a DSL is designed to be understandable and compact.   Unlike working with a framework where hundreds of lines of code are required just to provide initialization, working with a DSL typically requires very little code. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;When you write code in a DSL the language is able to understand the programmer's intent and therefore is able to hide most of the complexity.   For example Jetfire understands that variables should be saved to persistent storage.   Therefore Jetfire does this automatically without the application programmer writing extra code.   Jetfire also knows if a variable is used inside a method that it doesn't need to be saved because that variable is only valid as long the method is executing.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Further reading:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href='http://www.code-magazine.com/Article.aspx?quickid=0903131'&gt;Why The Next Five Years Will Be About Languages&lt;/a&gt;&lt;br /&gt;			&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8758015768402269586?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8758015768402269586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8758015768402269586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8758015768402269586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8758015768402269586'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2009/03/why-domain-specific-language-is-better.html' title='Why a Domain Specific Language is better than a Framework!'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2404838627295820545</id><published>2008-11-12T11:38:00.001-05:00</published><updated>2010-06-11T20:15:02.971-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Policy based Management with Jetfire</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;We have started an exciting new phase of Jetfire development.   Our next release is planned to support both a rules engine and transparent access to .net objects.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Using Jetfire source code a rule will look like the following:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://www.trackerrealm.com/blogimages/111208_1638_Policybased1.png'/&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;It needs to be mentioned that Jetfire code is not what the rule writer or rule user would see.   They would, in all likelihood, see some sort of form based interface.   Using Jetfire it extremely easy to write such an interface since it supports programmatically accessing the code for the rule.   The Jetfire code is presented here for understandability.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;How the rule code operates is that when an event occurs, in the above example when a 'property' is changed in any 'MailStats' object, parameters are generated for the rule.   In the example above the 'mailStats' and 'user' parameters are extracted from the event parameters.   Think of this as automatic method overloading.   These parameters provide a context for the rule and naturally if a parameter was requested that didn't exist in the event object it would cause a coding error.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Any legitimate code is allowed within the 'condition', including calling other rules.  Calling methods within a 'condition' is not allowed unless the method is deemed to be 'rule safe'.   In other words helper methods are allowed such as converting from a string to integer.   This allows the compiler to check the integrity of the rule 'condition' and insure that the 'when' events are sufficient.&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;Jetfire Policy Based Management Advantages&lt;br /&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Jetfire rules are easy to code and understand.   The built-in integrity features makes the rules very robust.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The ability to access .net objects means that Jetfire Rules can operate with existing data.   That is there is no need to convert data.   The data required for a Rule is in a database it can be easily accessed using a .net Framework such as ADO.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Since Jetfire is interpreted rules can be changed without recompilation or binding.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Code changes will not impact existing working rules since Jetfire includes automatic code version control.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Since Jetfire is a highly reflective language it is easy to present the user with friendly forms based rule system.&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2404838627295820545?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2404838627295820545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2404838627295820545' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2404838627295820545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2404838627295820545'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/11/policy-based-management-with-jetfire.html' title='Policy based Management with Jetfire'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-5976520529078389185</id><published>2008-11-11T20:09:00.001-05:00</published><updated>2008-11-17T22:48:52.242-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Navigating in Visual Studio</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;I work with Solutions that contain hundreds of files.  Navigating through many levels of directories can be a cumbersome task, especially when you are not the author of the Solution.  In university, using Visual Studio for assignments was never a problem, since you get to architect the structure of the Solution.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Working with a larger Solution, I was constantly performing Searches on desired keywords.  This worked, but very time consuming.  I needed to speed things up to increase my productivity.  I wanted a mechanism to remember where sections of code are located within the Solution.  Here are a couple of tips that can help:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;h2&gt;Tip #1: Using Bookmarks&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;Visual Studio has a Bookmarks feature that allows you to save a specific line in a specific file.  They work exactly like bookmarks used in web browsers.  Simply press Ctl+k and Ctl+k to save the line as a bookmark.  Note that you need to do Ctl+k twice, as I presume Visual Studio is starting to run out of shortcut keys!  Once the bookmark has been saved, you can view the bookmark in the Bookmarks window that can be docked at the bottom of your window:&lt;br /&gt;&lt;/p&gt;&lt;p style='text-align: center'&gt;&lt;span style='color:black; font-family:Times New Roman; font-size:0pt; background-color:black'&gt;&lt;br /&gt;				&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Instead of using the filename as the Bookmark title, try placing a comment as the title instead to remind yourself the importance of the said file, or even a "TODO" comment.  I have a handful of bookmarks for files I have edited so I can quickly re-visit the file if need be.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;h2&gt;Tip #2: Track item in Solution Explorer&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;Another tip to help navigate Visual Studio is to enable "Track Active Item in Solution Explorer".  This allows any active file to be highlighted in the Solution Explorer.  This comes in very handy when performing Searches, since double clicking a result highlights the file in Solution Explorer, giving you a general idea of the location of the file within the Solution.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This option can be enabled through Tools -&amp;gt; Options -&amp;gt; Projects and Solutions.&lt;br /&gt;&lt;/p&gt;&lt;p style='text-align: center'&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;This behaviour is actually enabled by default, but for whatever reason, this feature was disabled one day.  I went through days without this feature, so I finally made the effort to scan the long list of options under the Options dialog, and it was worth it!&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-5976520529078389185?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/5976520529078389185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=5976520529078389185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/5976520529078389185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/5976520529078389185'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/11/navigating-in-visual-studio_11.html' title='Navigating in Visual Studio'/><author><name>SW</name><uri>http://www.blogger.com/profile/04295191248583775465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2579975746904881303</id><published>2008-10-28T21:33:00.001-04:00</published><updated>2008-11-12T08:07:41.097-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Building a Color Editor using COR</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;Check out the &lt;a href="http://www.codeplex.com/AjaxColorPicker"&gt;AJAX Color Editor control&lt;/a&gt; for a control that displays a color picker. This project includes source code that shows how to incorporate the Web Control in an ASP.NET page. The Color Picker is based on AJAX technology that provides partial rendering for the control, giving it the feel of a fat client.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Table 1 displays the Color Picker. The control displays 2 color palettes – one for the back color and the second for the fore color. The sample text to color shows the selected back and fore colors.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt="" src="http://trackerrealm.com/BlogImages/102908_0133_BuildingaCo1.png" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The Color Picker uses:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;a href="http://codeplex.com/COR"&gt;COR project&lt;/a&gt; provides a set of &lt;span style="font-family:Trebuchet MS;font-size:9;color:black;"&gt;public static methods for adding Controls.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;AJAX technology provides partial rendering for the control, giving it the feel of a fat client&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;COR Project&lt;br /&gt;&lt;/h3&gt;&lt;p&gt;The Color Picker is a Web Control. It is created programmatically using public static methods from the 'C' class in COR.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2579975746904881303?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2579975746904881303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2579975746904881303' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2579975746904881303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2579975746904881303'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/10/building-color-editor-using-cor.html' title='Building a Color Editor using COR'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8342003154752077638</id><published>2008-10-19T18:27:00.001-04:00</published><updated>2010-06-11T20:15:02.972-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>FAQs for COR - A Web Site Building Tool</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;&lt;strong&gt;Q: What is COR?&lt;/strong&gt;&lt;br/&gt;A: &lt;span style='font-family:Segoe UI; font-size:9pt'&gt;COR is software that helps power users to become Web gurus by letting them build and maintain Web Sites. Users, with only browser, can log on to the Web Site to modify or create pages. Pages employ templates that support the placement and editing of web parts by the user (shown below – notice the 'Edit' and 'Delete" controls).&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://www.trackerrealm.com/blogimages/101908_2226_FAQsforCOR1.jpg'/&gt;&lt;span style='font-family:Segoe UI; font-size:9pt'&gt;&lt;br /&gt;				&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q:  How is COR different from web pages built using Microsoft ASP.net?&lt;br/&gt;&lt;/strong&gt;A:  COR is a small layer of management software that is built directly on top of &lt;a href='http://en.wikipedia.org/wiki/ASP.NET'&gt;ASP.net 2.0&lt;/a&gt;.   It takes full advantage of ASP.net Web Parts to implement its functionality.   You get the full power of ASP.net 2.0 without requiring a software programmer for all, but the most complicated web pages.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: What Web Parts come with COR?&lt;br/&gt;&lt;/strong&gt;A: COR comes with a Library of &lt;a href='http://wiki.jetfire.ca/CORHelpTopics.ashx'&gt;30 Web Parts&lt;/a&gt;. One notable inclusion in the library is a Word Web Part. It allows users to update content using Microsoft Word. Tables, formatting, and pictures in the Word document are automatically converted to HTML by the Word Web Part.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: What are some of the other key features of COR?&lt;br/&gt;&lt;/strong&gt;A: COR directly supports a menu bar across the top of the page and a menu bars on either the side of the page.   COR also keeps track of the user's location in the WEB site by displaying "&lt;a href='http://en.wikipedia.org/wiki/Breadcrumb_(navigation)'&gt;bread crumbs&lt;/a&gt;".&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: What does COR stand for?&lt;br/&gt;&lt;/strong&gt;A: COR stands for &lt;strong&gt;C&lt;/strong&gt;ontrols &lt;strong&gt;O&lt;/strong&gt;n the &lt;strong&gt;R&lt;/strong&gt;ight.   This is because when a user is editing a page the controls are displayed on the right hand side of the page.  The example below shows the 'controls on right' being employed to add a web part to the header area of the page.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://www.trackerrealm.com/blogimages/101908_2226_FAQsforCOR2.jpg'/&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: Why did you build COR?&lt;br/&gt;&lt;/strong&gt;A:  We built COR because we needed something to build our own WEB sites.  We started by building our Web sites using just ASP.net pages and eventually evolved to COR.  We also use COR to build Jetfire Workflow solutions.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: Why not just use SharePoint?&lt;br/&gt;&lt;/strong&gt;A:  Microsoft SharePoint is a wonderful product.   Many of the features of COR look very similar to SharePoint.   COR; however is a much lighter product that is focused on building Web sites.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: How much does COR cost?&lt;br/&gt;&lt;/strong&gt;A: COR is free.  The source code is available and does not have any restrictive licensing requirements (BSD license).   See &lt;a href='http://trackerrealm.com/blogs/2008/06/cor-why-make-it-free.html'&gt;COR-Why make it free?&lt;/a&gt;  and &lt;a href='http://trackerrealm.com/blogs/2008/06/open-source-license-favorites.html'&gt;Open Source License Favorites&lt;/a&gt; for more details.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: How can I extend COR or add a new WEB Part?&lt;/strong&gt;&lt;br/&gt;A:  COR is well documented and uses standard Microsoft programming patterns.   An experienced programmer should have no trouble extending COR or adding a Web Part.  Naturally, we can be contracted to add new features or build new Web Parts (&lt;a href='http://www.trackerrealm.com/pages/ContactUs.aspx'&gt;contact us&lt;/a&gt;).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: Where can I download COR?&lt;/strong&gt;&lt;br/&gt;A:  &lt;a href='http://www.codeplex.com/cor'&gt;www.codeplex.com/cor&lt;/a&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: What is the difference between DotNetNuke and COR?&lt;/strong&gt;&lt;br/&gt;A: DotNetNuke employs Web controls and is based on .Net 1.1.  Pages in DotNetNuke are built by programmers.  COR uses &lt;a href='http://en.wikipedia.org/wiki/Web_part'&gt;Web Parts&lt;/a&gt; and is based on .net 2.0.  Pages in COR are built by privileged user(s).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: What is required get a Web site running using COR?&lt;/strong&gt;&lt;br/&gt;A: COR can use, as the server, any Windows or Vista PC that supports &lt;a href='http://en.wikipedia.org/wiki/Internet_Information_Services'&gt;Internet Information Services&lt;/a&gt; and &lt;a href='http://msdn.microsoft.com/en-us/library/aa480476.aspx'&gt;Forms authentication&lt;/a&gt;.  Many ISPs support this configuration.   The ISP we use is &lt;a href='http://www.lfchosting.com/'&gt;LFC Hosting&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q: Are there some examples of sites that use COR?&lt;br/&gt;&lt;/strong&gt;A: yes. &lt;br /&gt;&lt;/p&gt;&lt;p style='margin-left: 36pt'&gt;&lt;a href='http://www.Jetfire.ca'&gt;&lt;span style='font-family:Verdana'&gt;Jetfire&lt;/span&gt;&lt;/a&gt;&lt;span style='font-family:Verdana'&gt;&lt;span style='color:navy'&gt;&lt;br/&gt;&lt;a href='http://oawa.ca/'/&gt;&lt;/span&gt;Ontario Amateur Wrestling Association&lt;span style='color:navy'&gt;&lt;br/&gt;&lt;a href='http://wrestling-ottawa.ca/default.aspx'/&gt;&lt;/span&gt;National Capital Wrestling Club&lt;span style='color:navy'&gt;&lt;br/&gt;&lt;a href='http://ottawawrestling.ca/'/&gt;&lt;/span&gt;Ottawa Wrestling Festival&lt;span style='color:navy'&gt;&lt;br/&gt;&lt;a href='http://canadacupofwrestling.ca/'/&gt;&lt;/span&gt;Canada Cup&lt;span style='color:navy'&gt;&lt;br/&gt;&lt;a href='http://arbutusassociates.ca/pages/Design.aspx'/&gt;&lt;/span&gt;Arbutus Associates&lt;/span&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;&lt;strong&gt;See Also&lt;/strong&gt;&lt;br/&gt;&lt;a href='http://trackerrealm.com/blogs/2008/06/cor-why-make-it-free.html'&gt;COR-Why make it free?&lt;/a&gt;&lt;br/&gt;&lt;a href='http://trackerrealm.com/blogs/2008/06/open-source-license-favorites.html'&gt;Open Source License Favorites&lt;/a&gt;&lt;br/&gt;&lt;a href='http://www.codeplex.com/COR'&gt;Download COR from CodePlex&lt;/a&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8342003154752077638?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8342003154752077638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8342003154752077638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8342003154752077638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8342003154752077638'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/10/faq-cor-web-site-building-tool.html' title='FAQs for COR - A Web Site Building Tool'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-812594001727752949</id><published>2008-10-12T13:16:00.001-04:00</published><updated>2010-06-11T20:15:02.973-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Displaying Line Numbers in Visual Studio</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;&lt;span style='font-family:Arial'&gt;You would think that the display of line numbers should just be automatic when using Visual Studio 2005 or 2008.  After all when using a C# compiler all the errors are given by a line number.  Also when exceptions occur the stack traces gives the line numbers of the stack (procedure calls) and the line number of the offending code that caused the exception.  Unfortunately, by default the line numbers are not visible when viewing the code in Visual Studio.  In fact many programmers work for months and even years before finding this important setting.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Arial'&gt;To display line numbering in Visual Studio 2005 or Visual Studio 2008 click the following sequence. &lt;strong&gt;&lt;br /&gt;					&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Arial'&gt;&lt;strong&gt;Tools/Options/Text Editor/C#/General and select "Display/Line Numbers".&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://www.trackerrealm.com/blogimages/101208_1715_DisplayingL1.png'/&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;&lt;span style='font-size:10pt'&gt;&lt;span style='font-family:Times New Roman'&gt;&lt;strong&gt;Visual Studio C# text editor with line numbers off (default).  Note no line numbers.&lt;/strong&gt;&lt;/span&gt;&lt;span style='font-family:Arial'&gt;&lt;br /&gt;					&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://www.trackerrealm.com/blogimages/101208_1715_DisplayingL2.png'/&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;&lt;span style='font-size:10pt'&gt;&lt;span style='font-family:Times New Roman'&gt;&lt;strong&gt;Select the Tools from the main menu bar, then Options.&lt;/strong&gt;&lt;/span&gt;&lt;span style='font-family:Arial'&gt;&lt;br /&gt;					&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://www.trackerrealm.com/blogimages/101208_1715_DisplayingL3.png'/&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;&lt;span style='font-size:10pt'&gt;&lt;span style='font-family:Times New Roman'&gt;&lt;strong&gt;Select Display/Numbers so that line numbers are displayed.&lt;/strong&gt;&lt;/span&gt;&lt;span style='font-family:Arial'&gt;&lt;br /&gt;					&lt;/span&gt;&lt;span style='font-family:Times New Roman'&gt;&lt;strong&gt;&lt;br /&gt;						&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt='' src='http://www.trackerrealm.com/blogimages/101208_1715_DisplayingL4.png'/&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Times New Roman; font-size:10pt'&gt;&lt;strong&gt;Visual Studio C# text editor with line numbers turned on.  Note the line numbers on left.&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='text-decoration:underline'&gt;&lt;strong&gt;Also See Related Postings&lt;br/&gt;&lt;a href='http://trackerrealm.com/blogs/2007/04/make-use-of-regions-when-developing-c.html'&gt;Using Regions&lt;/a&gt;&lt;br/&gt;&lt;a href='http://trackerrealm.com/blogs/2007/04/top-10-coding-guidelines-for-c.html'&gt;C#: Top 10 Coding Guidelines&lt;/a&gt;&lt;br /&gt;					&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-812594001727752949?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/812594001727752949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=812594001727752949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/812594001727752949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/812594001727752949'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/10/displaying-line-numbers-in-visual.html' title='Displaying Line Numbers in Visual Studio'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-3536081575202687171</id><published>2008-09-28T14:21:00.001-04:00</published><updated>2008-10-05T16:56:35.435-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><title type='text'>Adding ASP.NET Controls programmatically</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;If you design ASP.NET Web Controls or Composite Controls, you have designed controls programmatically. This approach is not as easy as using the Visual Designer in Visual Studio. This post explores the use of the "C class", which is part of the &lt;a href="http://codeplex.com/COR"&gt;COR download&lt;/a&gt;. The "C class" is a set of public static methods for adding Controls, managing strings, XML files and more.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Personally, once I started designing Web Parts, I did not want to go back to designing controls using the Visual Designer. I actually find it easier to place controls on the page and use logic to decide what controls are being placed on the page. However, designing Web Parts with standard Web Controls leads to much code. The "C class" allows design of controls with minimum code.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Let's review how a Label is added to a control:&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Label label = new Label();&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Label.ID = "ThisLabel";&lt;br /&gt;&lt;/p&gt;&lt;p&gt;label.Text = "The name to display";&lt;br /&gt;&lt;/p&gt;&lt;p&gt;label.Width = Unit.Pixel(200);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;label.CssClass = "AFormatOption";&lt;br /&gt;&lt;/p&gt;&lt;p&gt;this.Controls.Add(label);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It takes five statements just to add a simple label. For complex GUI's, it is easy to get lost in the number of lines required. I started thinking: "Why not have a simple method that adds the Label with a number of parameters?". E.g. Let's review what such a method would look like.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Using a method that does the work of assigning the values to the named properties&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Label label = AddLabelMethod("ThisLabel", "The name to display", "AFormatOption", Unit.Pixel(200), this);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The AddLabelMethod takes five parameters: ID, Text, CssClass, Width and an object that the label control is added to. The AddLabelMethod returns the new label object, which typically is not required because all the work is done in the AddLabelMethod.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The C class in COR is a set of helper methods that simplify the addition of Web Controls. To add a label,&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Using the AddLabel method is the C class simplifies programmatic design.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Label label = C.AddLabel ("ThisLabel", "The name to display", "", "AFormatOption", Unit.Pixel(200), this);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Note: ToolTip is added to the list of parameters. It is shown as a blank string in the example.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The C class, over 2000 lines of code at last count, contains a number of useful methods, including:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;AddTable, NewTableRow, NewTableCell&lt;br /&gt;&lt;/li&gt;&lt;li&gt;AddLabel, AddTextBox, AddLinkLabel, and a lot more&lt;br /&gt;&lt;/li&gt;&lt;li&gt;AddHiddenField and other methods to get and set the value of the hidden field&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Xml file management, e.g. GetAttribute, ReadXmlFile&lt;br /&gt;&lt;/li&gt;&lt;li&gt;AddUpdatePanel, AddUpdateProgress, AddTimer (recent additions)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;... and more&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I find using tables to place controls on the page is now simple. E.g&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Add a table to this control&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Table table = C.AddTable("table", Unit.Percentage(100), this);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Add the first Row&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;TableRow row = C.NewTableRow(table);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Add the first cell to the Row – it has text and a tooltip and is 100 pixels wide.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;C.NewTableCell(row, Unit.Pixel(100), "a name to display", "a tooltip for the cell", "CellFormat");&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Add a second cell to the Row.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;TableCell cell = C.NewTableCell(row);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#00b050;"&gt;// Add a text box to the second cell&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;C.AddTextBox("tb2", "", "Enter the name of something", "TextBoxFormat", Unit.Pixel(200), cell);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Using ASP.NET controls, this five-line sample would have taken about 20 lines of code. This approach has clear advantages:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Reduced footprint – The number of lines makes it easier to understand what is being done.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It is easier to add Comments that relate to what is being done.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The C class methods prompt the user for the typically used parameters. It is now easy to identify if any of the typical parameters have been forgotten.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The "C class" is available in the &lt;a href="http://codeplex.com/COR"&gt;COR download&lt;/a&gt; found on Code Plex.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Related posts include: &lt;a href="http://trackerrealm.com/blogs/2008/09/life-cycle-of-aspnet-controls_28.html"&gt;ASP.NET Life Cycle&lt;/a&gt;.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-3536081575202687171?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/3536081575202687171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=3536081575202687171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3536081575202687171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3536081575202687171'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/09/adding-controls-programmatically.html' title='Adding ASP.NET Controls programmatically'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-868658376386867306</id><published>2008-09-28T09:17:00.001-04:00</published><updated>2008-10-13T09:38:46.845-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><title type='text'>The Life Cycle of ASP.NET Controls</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Designing ASP.NET websites is easier if you understand the Life Cycle of the ASP.NET controls.  Let's review the ASP.NET controls (Refer to table 1). These include:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Page (Master Page)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;User Control&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Web Control&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Html Control&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Composite Control&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Web Part&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;From an object model perspective, the Life Cycle methods are derived from Control, Web Control and Composite Control.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The table presents ASP.NET controls mapped against Life Cycle methods.  This is what I think of as the 'get started' Life Cycle for controls. There are more Life Cycle methods, e.g. Pre-Init, if you want to manage Master Pages and Themes for a page.  Here are some observations:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You don't need to use all of the states when writing a control&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;You are best served if you match functionality to the correct Life Cycle method&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Your control will behave properly in all use cases.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Subtle bugs can occur because you have placed functionality in a non-optimal Life Cycle method&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse'&gt;&lt;colgroup&gt;&lt;col style='width:122px'/&gt;&lt;col style='width:127px'/&gt;&lt;col style='width:94px'/&gt;&lt;col style='width:85px'/&gt;&lt;col style='width:131px'/&gt;&lt;col style='width:79px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;&lt;tr style='background: #548dd4'&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Life Cycle Method&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Member of&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Page, User Control&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Web Control&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Composite Control, Web Part&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Html Control&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style='background: #c6d9f1'&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;&lt;strong&gt;Inherits from -&amp;gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;X&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;Control – Template Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;Control – Web Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Init&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;1&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;1&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;1&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;1&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Load Control State&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;2&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;2&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;3&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;2&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Load View State&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Web Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;3&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;3&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;4&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Load&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;4&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;4&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;3&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Create Child Controls&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;(Composite) Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt; &lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt; &lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;2 or 6 (See Note 1)&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Post back Event Handling&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Web Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;7&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;5&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Pre Render&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;6&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;6&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;8&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;6&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Save Control State&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;7&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;7&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;9&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;7&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Save View State&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Web Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;8&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;8&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;10&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Render&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Web Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;9&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;9&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;11&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Dispose&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;10&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;10&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;12&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;8&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Unload&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #c6d9f1; padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p&gt;Control&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;11&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;11&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;13&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt' vAlign='middle'&gt;&lt;p style='text-align: center'&gt;9&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;span style='color:#4f81bd; font-size:9pt'&gt;&lt;strong&gt;Table 1: Life Cycles of various ASP.NET Controls&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2&gt;Controls and the Life Cycle&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;Html Controls are simple controls that inherit from Control. As such, valid Life Cycle methods include: &lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Init&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Load Control State&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Load&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Post back event handling&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pre Render&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Save Control State&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Dispose&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Unload&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Page, User Control and Web Control includes the methods above, plus:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Load View State&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Save View State&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Render&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The Composite Control and Web Part include the base methods from above, plus:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create Child Controls&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Composite Controls&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;Being a Web Part designer means that I use Composite Controls. Composite Controls are different in that they have a Life Cycle method called 'CreateChildControls'.  (This is probably because of the history of Web Parts and SharePoint.) Here are a couple of notes from MSDN documentation on Composite Controls.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.compositecontrol.aspx'&gt;&lt;span style='font-family:Verdana; font-size:8pt'&gt;CompositeControl&lt;/span&gt;&lt;/a&gt; class is new in ASP.NET 2.0. If you created custom controls in ASP.NET version 1.0 or 1.1, you had to implement the &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx'&gt;&lt;span style='font-family:Verdana; font-size:8pt'&gt;INamingContainer&lt;/span&gt;&lt;/a&gt; interface to create a new naming scope for child controls. In addition, you had to override the &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.control.controls.aspx'&gt;&lt;span style='font-family:Verdana; font-size:8pt'&gt;Controls&lt;/span&gt;&lt;/a&gt; property and invoke the &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.control.ensurechildcontrols.aspx'&gt;&lt;span style='font-family:Verdana; font-size:8pt'&gt;EnsureChildControls&lt;/span&gt;&lt;/a&gt; method. In ASP.NET 2.0, these and other steps are performed by the &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.compositecontrol.aspx'&gt;&lt;span style='font-family:Verdana; font-size:8pt'&gt;CompositeControl&lt;/span&gt;&lt;/a&gt; class.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You should create the child controls in the &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.control.createchildcontrols.aspx'&gt;&lt;span style='color:blue; text-decoration:underline'&gt;CreateChildControls&lt;/span&gt;&lt;/a&gt; method and not in &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.control.oninit.aspx'&gt;&lt;span style='color:blue; text-decoration:underline'&gt;OnInit&lt;/span&gt;&lt;/a&gt; or another life cycle phase. The server control architecture relies on calls to &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.control.createchildcontrols.aspx'&gt;&lt;span style='color:blue; text-decoration:underline'&gt;CreateChildControls&lt;/span&gt;&lt;/a&gt; whenever the &lt;a href='http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.compositecontrol.controls.aspx'&gt;&lt;span style='color:blue; text-decoration:underline'&gt;Controls&lt;/span&gt;&lt;/a&gt; collection is needed, such as during data binding (if applicable). &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Note 1: When the Composite Control is displayed normally, 'CreateChildControls' is called AFTER the 'Load' method.  However, when a post back event occurs, 'CreateChildControls' is called AFTER the 'Init' method. This certainly makes the 'CreateChildControls' method  an "interesting" aspect of the Life Cycle.&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;References&lt;br /&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blogs.thesitedoctor.co.uk/tim/2006/06/30/Complete+Lifecycle+Of+An+ASPNet+Page+And+Controls.aspx'&gt;http://blogs.thesitedoctor.co.uk/tim/2006/06/30/Complete+Lifecycle+Of+An+ASPNet+Page+And+Controls.aspx&lt;/a&gt; – this shows a trace of the Life Cycles of MasterPage, Page, and various Controls. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='http://msdn.microsoft.com/en-us/library/ms178472.aspx'&gt;http://msdn.microsoft.com/en-us/library/ms178472.aspx&lt;/a&gt; - this describes the Page Life Cycle.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-868658376386867306?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/868658376386867306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=868658376386867306' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/868658376386867306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/868658376386867306'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/09/life-cycle-of-aspnet-controls_28.html' title='The Life Cycle of ASP.NET Controls'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-3540767309800789684</id><published>2008-07-26T15:41:00.001-04:00</published><updated>2008-10-25T10:56:04.239-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Quiz made easy</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;I just finished integrating the Jetfire Quiz into the system. The quiz that I wrote using the &lt;a href='http://codeplex.com/Jetfire'&gt;Jetfire&lt;/a&gt; scripting language was quite simple:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;What is your name? __________&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Are you over 18? (yes/no)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select an age category: 18 to 25, 26-35, 36 – 45, over 45&lt;br /&gt;&lt;/li&gt;&lt;li&gt;How often do you go dancing in a year? ___&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;From a code perspective, the Quiz is a set of Questions and Answers.  Answers may be text, numeric, yes/no, a selection from a list, date and time, and duration.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;A new Web Control is provided (in the website) to iterate over the list of Questions and Answers, providing the user with the ability to input answers.  The quiz can be &lt;a href='http://jetfire.ca/demo/Quiz.aspx'&gt;viewed&lt;/a&gt; using this custom control.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The real reason for this blog is to brag about just how simple it is to write your own Quiz. My friend, Mo, wrote a quiz in 30 minutes this morning.  Mo owns a Print shop in Ottawa, has a Computer Science degree from over 20 years ago and hasn't programmed in a whole lot of years.  Mo is a smart guy, but not a programmer.  He needed a little bit of help with syntax, but since he uses Excel extensively, he was a natural to write his first Jetfire workflow.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; Since I hit him cold with "you are designing a quiz right now", most of the time was spent formulating the questions and answers about the travel quiz that he wanted to write.  His &lt;a href='http://jetfire.ca/Code/Apps/QuizTravel.txt'&gt;travel quiz&lt;/a&gt; includes the following questions:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;What was your favorite destination? ________&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select your Sex: Male, Female&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select a destination: North America, Europe&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select an age category: Under 18, 18 – 35, 36- 50, over 50&lt;br /&gt;&lt;/li&gt;&lt;li&gt;How often do you travel in a year? ____&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Less than five minutes later, I had the privilege of being the first to fill in his quiz.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Sound like fiction? With Jetfire, you upload the Jetfire code and start using it immediately.  This is possible because Jetfire is a scripting language and re-uses the Question and Answer Web Control described above.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-3540767309800789684?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/3540767309800789684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=3540767309800789684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3540767309800789684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3540767309800789684'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/07/quiz-made-easy.html' title='Quiz made easy'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-3104759246807625325</id><published>2008-07-04T10:44:00.001-04:00</published><updated>2008-07-04T12:40:07.405-04:00</updated><title type='text'>Kudos to screwturn wiki </title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;This blog sends kudos to &lt;a href='http://www.screwturn.eu'&gt;screwturn.eu&lt;/a&gt;, the creators of a .NET open source wiki implementation. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;TrackerRealm has been looking for a wiki for the past year that we can use for documentation. After assessing over half a dozen versions of incomplete projects, I was getting extremely frustrated.  Then while looking for a new Blog engine one day, I noticed that the Blog engine company was using screwturn for their documentation – I went whoa! – this looks like a great wiki – I wonder how much it costs. Well, the &lt;a href='http://trackerrealm.com/blogs/2008/06/open-source-license-favorites.html'&gt;price is right&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Why do I like screwturn wiki?&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Ease of installation – it was installed on my PC in 10 minutes. (ScrewTurn store the page data in xml files vs a database) &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ease of skinning – I created a new theme for &lt;a href='http://wiki.jetfire.ca'&gt;http://wiki.jetfire.ca&lt;/a&gt; in 30 minutes. (I am not  a themes expert)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ease of administration – putting the admin password in the web.config makes it easy to change. Adding new accounts is trivial.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;New pages easily created&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ease in tailoring the templates, e.g. header, footer, side panels, etc&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Easy sums up what I think about our new screwturn wiki.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-3104759246807625325?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/3104759246807625325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=3104759246807625325' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3104759246807625325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3104759246807625325'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/07/kudos-to-screwturn-wiki.html' title='Kudos to screwturn wiki '/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8148835155824195376</id><published>2008-07-03T16:17:00.001-04:00</published><updated>2008-07-03T16:23:51.204-04:00</updated><title type='text'>New Blog Editor</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;I am writing this blog on my brand new blog editor – it's called Word 2007.  I love Word.  Word allows a user to post a blog to Blogger directly from Word 2007.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Word is simple - it lets me use an editor that I am familiar with and format my blog that way that I am comfortable with.  And it has a spell checker.  &lt;br /&gt;&lt;/p&gt;&lt;p&gt;How does it work?&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Open Word 2007&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select New from the Office icon&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select 'Create new blog'&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Enter Login information for Blogger&lt;br /&gt;&lt;/li&gt;&lt;li&gt;(optional) identify an image provider for uploading images (that you embed in Word)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Write Blogs in your favorite editor&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Save a draft copy of your blog to polish off later or Publish the draft to your blogger&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Once the Blog is finished, Publish the blog.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;One gotcha is that once you publish the blog and close the Word Editor, you must use Blogger's editor, UNLESS you save a copy of the blog locally and then re-edit it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;That's it – enjoy.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8148835155824195376?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8148835155824195376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8148835155824195376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8148835155824195376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8148835155824195376'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/07/new-blog-editor.html' title='New Blog Editor'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-944403322990242579</id><published>2008-06-25T18:05:00.001-04:00</published><updated>2010-06-11T20:21:41.896-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linq to sql'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><title type='text'>ADO.Net: The Good, The Bad and The Ugly</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;First I need to state that &lt;a href='http://en.wikipedia.org/wiki/ADO.NET'&gt;ADO.Net&lt;/a&gt; is &lt;span style='font-size:14pt'&gt;&lt;strong&gt;a very good component&lt;/strong&gt;&lt;/span&gt;.   It does an excellent job of what it was designed to do.  ADO.Net provides an object based representation of a database.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Some the excellent features ADO.Net are:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;DataTables:  Provide a memory representation of a database table (or combination of tables).   This allows software to directly read and write to the database data.   The ADO automatically takes care of &lt;a href='http://msdn.microsoft.com/en-us/library/cs6hb8k4(VS.80).aspx'&gt;concurrency issues&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/ADO.net'&gt;DataSets&lt;/a&gt;:  Provide a memory representation of a number of data table and the relationships between the tables.  With DataSets the &lt;a href='http://en.wikipedia.org/wiki/Database_schema'&gt;database schema&lt;/a&gt; can be represented in an object format.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;XML tools:  Provides ability to both input and output XML representations of data to and from data sets and data tables.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Serialization:  Data sets can be serialized allowing database data to be available via a web service or &lt;a href='http://en.wikipedia.org/wiki/.NET_Remoting'&gt;remote service&lt;/a&gt;.   This allows for &lt;a href='http://en.wikipedia.org/wiki/Fat_client'&gt;rich clients&lt;/a&gt; to have direct access to the database.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There is an issue with ADO.Net and Data Sets (&lt;a href='http://en.wikipedia.org/wiki/Talk:ADO.NET'&gt;summarized in this discussion on wikipedia&lt;/a&gt;), but that is not bad part.   &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-size:14pt'&gt;&lt;strong&gt;The bad part&lt;/strong&gt;&lt;/span&gt; is that ADO.Net falls short of the requirements to properly support &lt;a href='http://en.wikipedia.org/wiki/OOD'&gt;Object-Oriented design&lt;/a&gt; (OOD).   While doing an excellent job of providing an object oriented view of a SQL database, a SQL database itself is not very object oriented.   That is ADO.Net provides objects that map one to one to the features of database.  In the absence of any other components what typically happens is that ADO.Net is used directly with application code.  Even with careful planning it can still result in these bad design practices:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;OOD tenant of &lt;a href='http://en.wikipedia.org/wiki/Information_hiding'&gt;encapsulation&lt;/a&gt; is violated.  What occurs when ADO is used is that many of the SQL database issues are not encapsulated, but brought into the application code.  &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Complex objects and especially &lt;a href='http://en.wikipedia.org/wiki/Object_composition'&gt;object composition&lt;/a&gt; are not used.  Databases only support the storage of &lt;a href='http://en.wikipedia.org/wiki/Primitive_types'&gt;built-in types&lt;/a&gt;.   The result is that the application objects that deal with the database data tend not to use software structures such as queues, FIFOs, collections, and references (object composition).   Instead application objects use the built-in types almost exclusively and use the &lt;a href='http://en.wikipedia.org/wiki/Foreign_key'&gt;database foreign key structures&lt;/a&gt; directly, instead of references.  In fact the code is likely not to be object oriented at all.  &lt;br /&gt;&lt;/li&gt;&lt;li&gt;There is significant code that needs to be created that is dedicated to ADO configuration, setting up data tables/data sets, reading and writing to database, etc.  This isn't bad code; the bad part is that it needs to be written, tested, deployed and maintained.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This results in really &lt;span style='font-size:14pt'&gt;&lt;strong&gt;ugly application code&lt;/strong&gt;&lt;/span&gt;.   This ugly code has a number of nasty features:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Software and the database must be changed at same time.  Typically changing the database schema requires changing the application software.   Adding new features requires not only adding the new objects, but insuring the database is also changed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The issue of versioning the database schema and software needs to be accommodated.  For example when new features require database changes there needs to be a deployment process where the existing databases are upgraded.  Alternately the software needs to handle both the old and new database schema. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;The application code becomes larger than it needs to be in order to handle that lack of true objects in a database.  Bugs become harder to fix.   New features become more difficult to add.  The code just becomes harder to understand because of its size, lack of encapsulation and use of &lt;a href='http://en.wikipedia.org/wiki/Structured_programming'&gt;structured programming&lt;/a&gt;&lt;br /&gt;					&lt;a href='http://en.wikipedia.org/wiki/Structured_programming'&gt;instead of object programmer techniques&lt;/a&gt;.&lt;br/&gt;&lt;br /&gt;				&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This begs the question, how should you employ OOD and still use a database?   One answer is to use an &lt;a href='http://en.wikipedia.org/wiki/Object-relational_mapping'&gt;object-relational mapping&lt;/a&gt; technique such as is provided by &lt;a href='http://en.wikipedia.org/wiki/NHibernate'&gt;Hibernate&lt;/a&gt; or product such as &lt;a href='http://en.wikipedia.org/wiki/Db4o'&gt;DB4O&lt;/a&gt; that makes a standard SQL database look like an object oriented database.   These are good, but have their draw backs.  Fortunately there will shortly be solution from Microsoft that extends ADO.Net called &lt;a href='http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework'&gt;ADO.Net Entity Framework&lt;/a&gt;.   It may not solve all the "ugly code" issues and will certainly have some drawbacks, but is very promising.   We are excited by it. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href='http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework'&gt;ADO.Net Entity Framework&lt;/a&gt; is a very attractive solution since it is not only provides an object-relational mapping service, but will provide Query support using &lt;a href='http://en.wikipedia.org/wiki/LINQ'&gt;LINQ&lt;/a&gt; as well as integrating tightly with Visual Studio.   This is great, but in my opinion the biggest advantage of the Entity Framework is that it allows new, and even ongoing, software projects to use OOD while using existing databases, existing database tools and practices.  In other words the &lt;span style='font-size:12pt'&gt;&lt;strong&gt;substantial investment in databases can be protected&lt;/strong&gt;&lt;/span&gt;, while building OOD software to exploit it.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-944403322990242579?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/944403322990242579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=944403322990242579' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/944403322990242579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/944403322990242579'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/06/adonet-good-bad-and-ugly.html' title='ADO.Net: The Good, The Bad and The Ugly'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8610138103043179566</id><published>2008-06-20T11:54:00.001-04:00</published><updated>2008-06-20T15:27:20.020-04:00</updated><title type='text'>Open Source License Favorites</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;There are lots of &lt;a href='http://en.wikipedia.org/wiki/Open-source_license'&gt;open source licenses&lt;/a&gt; in existence.  Some are general purpose and some are very specific.   Our favorites are &lt;a href='http://en.wikipedia.org/wiki/Bsd_license'&gt;BSD&lt;/a&gt; and &lt;a href='http://en.wikipedia.org/wiki/GNU_General_Public_License'&gt;GNU GPL&lt;/a&gt;.  Many of the other open source licenses are variations of these 2 classics.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;BSD is the most permissive of the 'open source' licenses.   When software has a BSD license it is practically in the &lt;a href='http://en.wikipedia.org/wiki/Public_domain'&gt;public domain&lt;/a&gt;.   The only real requirement of the license is a citation provision where if BSD software is incorporated into another product, its usage must be acknowledged.  Other than that provision BSD licensed code can be incorporated into other products with no restrictions.  As software developers we have no qualms about using BSD licensed code.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;GNU license is a little more restrictive.   If you use a GNU GPL application, for example to build a web site, it is free.  It is free even if you make money from the Web site.   If, on the other hand, you incorporate GNU GPL code in your product you must make your product GNU GPL licensed as well.  For products that are developed for profit this is a very restrictive requirement.   This is why most GNU software is also available with a commercial license allowing incorporation into proprietary products.  Jetfire is available with a GNU General Public License as well as a commercial license.   Here is an &lt;a href='http://www.db4o.com/about/productinformation/whitepapers/db4o%20Whitepaper%20-%20db4objects%20and%20the%20Dual%20Licensing%20Model.pdf'&gt;excellent article on GNU vs commercial license.&lt;/a&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;For us when we ship a product with a BSD license we want it used everywhere.  One of our goals is to get consulting revenue from customers who want special features.  Another goal is to release other products that rely on it.  For example Jetfire WebParts operate on top of our BSD licensed COR product.  &lt;span style='text-decoration:underline'&gt;Our primary goal&lt;/span&gt;; however is to get attention from delivery of a valuable, quality free software product.  In we effect advertising our capabilities.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;When we license a product with GNU our strategy is to get is used everywhere as well, but with the twist that if it is used commercially we are also looking for revenue.  We are willing to sacrifice some usage that a more permissive license would afford in return for getting revenue.   Many non-commercial applications will pay for the commercial license simply to get enhanced support.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8610138103043179566?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8610138103043179566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8610138103043179566' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8610138103043179566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8610138103043179566'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/06/open-source-license-favorites.html' title='Open Source License Favorites'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-850956826707601874</id><published>2008-06-19T16:22:00.000-04:00</published><updated>2010-06-11T20:23:26.552-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Engineering'/><title type='text'>COR - Why make it free?</title><content type='html'>&lt;a href="http://trackerrealm.com/blogs/uploaded_images/COR_WebPart-791371.JPG"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://trackerrealm.com/blogs/uploaded_images/COR_WebPart-791355.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;COR, which stands for 'Controls On the Right', provides the foundation block allowing mere mortals to build and maintain web sites. That is the goal behind our new &lt;a href="http://en.wikipedia.org/wiki/BSD_License"&gt;BSD licensed&lt;/a&gt; project.&lt;br /&gt;&lt;br /&gt;Briefly, COR is a project available on &lt;a href="http://en.wikipedia.org/wiki/CodePlex"&gt;CodePlex&lt;/a&gt; that allows anyone to become a guru at designing and building web sites. You probably need an expert to set it up, but once set up 'mere mortals' can develop pages and update content. It also helps if you have a graphic artist to help with the color schemes and provide some banner graphics.&lt;br /&gt;&lt;br /&gt;We built COR because we were tired of building our site. We didn't have a lot money to hire someone build and maintain our site, so we needed to do it. We quickly became tired of constantly hand coding HTML and patching pages together from a half dozen tools. After re-building the same page a number times by hand we decided we were going to automate. Our goal for COR was that only a Web browser was required to build or change Web pages. The running joke was "After all, how hard can it be?". Well as it turns out it is always harder (and takes longer) than you think, but using ASP.Net 2.0 it was manageable. In fact using a lot of tools in .Net bag, such as the &lt;a href="http://msdn.microsoft.com/en-us/library/aa480476.aspx#pagexplained0002_overview"&gt;Forms Authentication&lt;/a&gt;, made the entire effort viable.&lt;br /&gt;&lt;br /&gt;We really liked the modular &lt;a href="http://en.wikipedia.org/wiki/Web_part"&gt;Web Part &lt;/a&gt;concept and the way SharePoint allows users to create Web pages. We would have used SharePoint, but our ISP, as is the case with most ISPs, didn't support SharePoint. So both Web Parts and SharePoint style web page editing is a key feature of COR.&lt;br /&gt;&lt;br /&gt;We use COR internally because we are also mere mortals. Our websites &lt;a href="http://www.trackerrealm.com/"&gt;http://www.trackerrealm.com/&lt;/a&gt; and &lt;a href="http://www.jetfire.ca/"&gt;http://www.jetfire.ca/&lt;/a&gt; are built with it. We also have numerous other websites using it. We like it. We like it so much that we think it should be everywhere. We'd like to get paid for COR, but that is just not going to happen. So we decided to go for fame and glory. What better way to do that then to make it freely available, with source code, and a very permissive license.&lt;br /&gt;&lt;br /&gt;Finally COR is a foundation block for our Jetfire Web offerings.  Check out &lt;a href="http://www.codeplex.com/COR"&gt;Cor on Codeplex&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-850956826707601874?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/850956826707601874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=850956826707601874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/850956826707601874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/850956826707601874'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/06/cor-why-make-it-free.html' title='COR - Why make it free?'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-3843697255830742451</id><published>2008-06-12T14:57:00.000-04:00</published><updated>2010-06-11T20:19:30.445-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Hello World with Jetfire</title><content type='html'>It has become a tradition the first program to introduce a user to a programming language &lt;a href="http://en.wikipedia.org/wiki/Hello_world_program"&gt;is "Hello World". &lt;/a&gt;We thought it would be appropriate to have a "Hello World" program for &lt;a href="http://jetfire.ca/"&gt;Jetfire&lt;/a&gt; &lt;a href="http://www.codeplex.com/jetfire"&gt;(download site)&lt;/a&gt; as well; however we were concerned that it didn't really show how Jetfire is different from everything else. Well that is the point. Jetfire it is not different when it comes to writting code to solve a problem, but it is radically different, in that it is a whole lot simpler, when you try to solve real world problems with Jetfire.&lt;br /&gt;&lt;br /&gt;Well what do we mean by a lot simpler. Well lets look at "Hello World".&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;&lt;span&gt;namespace test&lt;br /&gt;{&lt;br /&gt;   workflow HelloWorld&lt;br /&gt;   {&lt;br /&gt;      DateTime creationTime = DateTime.Now;&lt;br /&gt;      public string Hello&lt;br /&gt;      {&lt;br /&gt;           get{return "This workflow was created at:" + creationTime.ToString();}&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/span&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;&lt;br /&gt;On the surface it looks almost like C#. The only significant difference is that 'class' has been replaced by 'workflow'. Other than that it is valid C# code.&lt;br /&gt;&lt;br /&gt;So what is the difference? Why bother with Jetfire? Well the big difference is that Jetfire really starts where C# ends. For example, once a Jetfire instance of the HelloWorld object is created it is persistent until it is deleted. That is why there is a time stamp in this example so you could see when each instance was created. &lt;a href="http://www.jetfire.ca/demo/HelloWorld.aspx"&gt;Try it for yourself.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In C# to make an object persistent you need to write code to save it to database or a file. Yes, you can serialize the object; however then serialization breaks if you change the code, and so on. With Jetfire there is nothing more to do. The objects and code are persitent. When the code changes a new version is automatically created.&lt;br /&gt;&lt;br /&gt;This is part of goal of having the programmer focus on the problem, not the programming infrastructure. Hopefully the "HelloWorld" example gives some introductory insight to the features of &lt;a href="http://jetfire.ca/"&gt;Jetfire&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-3843697255830742451?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/3843697255830742451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=3843697255830742451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3843697255830742451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3843697255830742451'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2008/06/hello-world-with-jetfire.html' title='Hello World with Jetfire'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2474923942382862691</id><published>2007-09-28T21:51:00.001-04:00</published><updated>2008-04-17T16:52:14.701-04:00</updated><title type='text'>Auto-Display for Workflows</title><content type='html'>In talking with customers about the workflow creation process, one customer got quite excited about how quick and easy it is to create a workflow. Suddenly, the customer asked, "If I can create a workflow this fast, I want to create a lot of workflows. Can I display the workflow using some existing GUI without having to design a custom GUI?".&lt;br /&gt;&lt;br /&gt;Custom GUI's take time to create. The objective of Jetfire is to simplify the workflow creation/modification process so that Power Users can build workflows and upgrade them. But what good is a simple workflow creation process if there is no GUI to use it?&lt;br /&gt;&lt;br /&gt;This is a common problem with workflow systems. I have not seen a workflow system that provides a user GUI that adapts to new workflows. However, with the experience from Tracker, we decided that a general GUI is best addressed by a data-driven system.&lt;br /&gt;&lt;br /&gt;Using Web Parts, we created a set of Web Parts that provide a general purpose workflow display for Jetfire. (see &lt;a href="http://jetfire.ca/pages/JetfireWebParts.aspx"&gt;http://Jetfire.ca/pages/JetfireWebParts.aspx&lt;/a&gt; for more informaiton.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2474923942382862691?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2474923942382862691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2474923942382862691' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2474923942382862691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2474923942382862691'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/09/auto-display-for-workflows.html' title='Auto-Display for Workflows'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-254321682422690853</id><published>2007-09-28T21:24:00.000-04:00</published><updated>2007-09-28T21:48:45.300-04:00</updated><title type='text'>Silverlight 1.0 Released</title><content type='html'>Sep 19, 2007&lt;br /&gt;Jason Beres from Infragistics in Boston, Mass was the guest speaker at Ottawa dot net community Events speaking about Silverlight.  Silverlight was just released on Sep 5.&lt;br /&gt;&lt;br /&gt;We have been testing CTP's for WPF/E, now called Silverlight, since 0.8 release. There have been some subtle changes in the interface definitions. In upgrading our Silverlight projects from 0.9 to 1.0 (see &lt;a href="http://www.trackerrealm.com/blogs/WPFEControls/images.htm"&gt;http://www.trackerrealm.com/blogs/WPFEControls/images.htm&lt;/a&gt;), we noticed the following changes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Javascript is no longer a part of the Xaml file.  Events have moved from the Xaml file to a "code behind"Microsoft Javascript file using an &lt;strong&gt;AddEventListener&lt;/strong&gt; method.&lt;/li&gt;&lt;li&gt;I refer to it as a Microsoft Javascript file, because it does not conform to the standard JS file format.  Rather, Microsoft have created a Javascript object model. &lt;/li&gt;&lt;li&gt;A number of Xaml Control properties are gone. (not deprecated, but gone)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Meanwhile, back to Jason - fantastic presenter and presentation. Jason discussed Silverlight 1.0 and 1.1. He juggled back and forth between the formal release and the CTP highlighting differences.  Key points:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Silverlight is Microsoft's competitor to Adobe Flash. (great graphics and animation.)&lt;/li&gt;&lt;li&gt;Silverlight is a cross-browser plug-in.  &lt;/li&gt;&lt;li&gt;Silverlight is Xaml-based.&lt;/li&gt;&lt;li&gt;Silverlight is a stand-alone product, ie. not dependent on .net. (Microsoft are integrating base classes from .net)&lt;/li&gt;&lt;li&gt;Silverlight 1.0 release is 4.6 MB. (expect Silverlight 1.1 release to be about 7 MB)&lt;/li&gt;&lt;li&gt;Silverlight language for the code behind file in 1.0 is Javascript&lt;/li&gt;&lt;li&gt;Silverlight language for the code behind file in 1.1 is C# and VB.net&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-254321682422690853?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/254321682422690853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=254321682422690853' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/254321682422690853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/254321682422690853'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/09/silverlight-10-released.html' title='Silverlight 1.0 Released'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-1976309695990379917</id><published>2007-09-26T18:03:00.000-04:00</published><updated>2008-10-25T10:59:33.657-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Jetfire is born</title><content type='html'>Blogging has taken a back seat over the past few months while we have been working on Jetfire - a new approach to designing workflows. Well, Jetfire has arrived and blogs should start coming.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-1976309695990379917?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/1976309695990379917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=1976309695990379917' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1976309695990379917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1976309695990379917'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/09/jetfire-is-born.html' title='Jetfire is born'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-245404386475310051</id><published>2007-09-26T17:09:00.000-04:00</published><updated>2008-10-25T10:59:13.938-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>Jetfire debut at Ottawa Demo Camp</title><content type='html'>Monday, Sep 24, 2007&lt;br /&gt;John and Charlie present Jetfire Workflows to an Ottawa developer audience. (See FAQ at &lt;a href="http://jetfire.ca/pages/JetfireFAQ.aspx"&gt;http://Jetfire.ca/pages/JetfireFAQ.aspx&lt;/a&gt; for more info.)&lt;br /&gt;&lt;br /&gt;The demo showed a DVD Tracking application. DVD's are added to Jetfire and tracked by Home, On Loan, Lost and Dead states. Commands, e.g. Lost, Found, Died) and Properties (On Loan To, Loan Timestamp, Returned Timestamp, and Lost Timestamp) are displayed on a general Web Demo available to ALL Jetfire workflows.&lt;br /&gt;&lt;br /&gt;The Jetfire code, written in a C#,Java-like language was developed by John and Charlie at TrackerRealm. The language is workflow specific and makes it quick and easy to write workflows.&lt;br /&gt;&lt;br /&gt;Demo key figures include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Multi-language strings (see English and Swedish-Chef instructions)&lt;/li&gt;&lt;li&gt;Command Method and Property filtering by state (only see what you need to see)&lt;/li&gt;&lt;li&gt;Change state (uses keyword: 'enterstate')&lt;/li&gt;&lt;li&gt;Enter 'On Loan To' name causes state change, On Loan To Timestamp to be automatically updated&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Bottom line: Comments like "Is that all the code there is?" tells me that we are on the right track.&lt;/p&gt;&lt;p&gt;Test Drive Jetfire yourself at &lt;a href="http://jetfire.ca/Pages/JetfireDownload.aspx"&gt;http://jetfire.ca/Pages/JetfireDownload.aspx&lt;/a&gt;&lt;/p&gt;The DVD workflow (100 lines of code) is shown at &lt;a href="http://jetfire.ca/Code/Apps/DVDInventory.txt"&gt;http://jetfire.ca/Code/Apps/DVDInventory.txt&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-245404386475310051?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/245404386475310051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=245404386475310051' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/245404386475310051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/245404386475310051'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/09/jetfire-debut-at-ottawa-demo-camp.html' title='Jetfire debut at Ottawa Demo Camp'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2983611102045055811</id><published>2007-05-01T10:44:00.000-04:00</published><updated>2007-05-01T14:36:05.778-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF/E'/><category scheme='http://www.blogger.com/atom/ns#' term='SilverLight'/><title type='text'>Using Code Creator to Create SilverLight Controls (WPF/E)</title><content type='html'>SilverLight is small, efficient and has the promise of making great Web experiences for the browser user.   To fufill this promise SilverLight code (Xml) must be created dynamically.   This can be done via JavaScript in the client browser or at the server.  We believe using CodeCreator at the server is a much simpler, faster and more maintainable approach.&lt;br /&gt;&lt;br /&gt;Below is an example of a SilverLight control with CodeCreator constructs.  This can be used to dynamically create a &lt;a href="http://www.trackerrealm.com/blogs/WPFEControls/images.htm"&gt;control demonstrated in this link&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;  &lt;pre&gt;&lt;em&gt;&lt;strong&gt;&lt;span style="Color:green"&gt;&amp;lt!--&amp;ltcc:Repeat/&amp;gt--&amp;gt&lt;/span&gt;&lt;br /&gt;  &amp;ltCanvas &amp;gt   &lt;br /&gt;    &amp;ltRectangle x:Name="button0"&lt;br /&gt;               Width="120"&lt;br /&gt;               Height="75"&lt;br /&gt;               Canvas.Left="0"&lt;br /&gt;               Canvas.Top="0"&lt;br /&gt;               Stretch="Fill"&lt;br /&gt;               MouseEnter="javascript:ImageButtonEnter"&lt;br /&gt;               MouseLeave="javascript:ImageButtonLeave"&lt;br /&gt;               MouseLeftButtonDown='javascript:ImageButtonDown0'&lt;br /&gt;               &amp;gt&lt;span style="Color:green"&gt;&lt;br /&gt;      &amp;lt!--&amp;ltcc:Replace Attribute="Canvas.Top"&amp;gt$Top$&amp;lt/cc:Replace&amp;gt&lt;br /&gt;      &amp;ltcc:Replace Attribute="x:Name"&amp;gtbutton$Counter$&amp;lt/cc:Replace&amp;gt&lt;br /&gt;      &amp;ltcc:Replace Attribute="MouseLeftButtonDown"&amp;gt&lt;br /&gt;javascript:ImageButtonDown$Counter$&amp;lt/cc:Replace&amp;gt--&amp;gt&lt;/span&gt;&lt;br /&gt;      &amp;ltRectangle.Fill&amp;gt&lt;br /&gt;        &amp;ltImageBrush ImageSource="images/JetSki.jpg" &amp;gt&amp;lt/ImageBrush&amp;gt&lt;span style="Color:green"&gt;&lt;br /&gt;        &amp;lt!--&amp;ltcc:Replace Attribute="ImageSource"&amp;gt$Images$&lt;br /&gt;        &amp;lt/cc:Replace&amp;gt--&amp;gt&lt;br /&gt;      &lt;/span&gt;&amp;lt/Rectangle.Fill&amp;gt&lt;br /&gt;    &amp;lt/Rectangle&amp;gt&lt;br /&gt;  &amp;lt/Canvas&amp;gt&lt;span style="Color:green"&gt;&lt;br /&gt;  &amp;lt!--&amp;ltcc:Evaluate&amp;gtTop = Top + 30;&amp;lt/cc:Evaluate&amp;gt--&amp;gt&lt;br /&gt;  &amp;lt!--&amp;ltcc:Evaluate&amp;gtCounter = Counter + 1;&amp;lt/cc:Evaluate&amp;gt--&amp;gt  &lt;br /&gt;&amp;lt!--&amp;ltcc:RepeatEnd/&amp;gt--&amp;gt&lt;/em&gt;&lt;/strong&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;CodeCreator will create the following code.&lt;em&gt;&lt;strong&gt;&lt;pre&gt;  &amp;ltCanvas&amp;gt&lt;br /&gt;    &amp;ltRectangle x:Name="button0"&lt;br /&gt;               Width="120"&lt;br /&gt;               Height="75"&lt;br /&gt;               Canvas.Left="0"&lt;br /&gt;               Canvas.Top="0"&lt;br /&gt;               Stretch="Fill"&lt;br /&gt;               MouseEnter="javascript:ImageButtonEnter"&lt;br /&gt;               MouseLeave="javascript:ImageButtonLeave"&lt;br /&gt;               MouseLeftButtonDown="javascript:ImageButtonDown0"&lt;br /&gt;               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&amp;gt&lt;br /&gt;      &amp;ltRectangle.Fill&amp;gt&lt;br /&gt;        &amp;ltImageBrush ImageSource="images/cf18.jpg"&amp;gt&amp;lt/ImageBrush&amp;gt&lt;br /&gt;      &amp;lt/Rectangle.Fill&amp;gt&lt;br /&gt;    &amp;lt/Rectangle&amp;gt&lt;br /&gt;  &amp;lt/Canvas&amp;gt&lt;br /&gt;  &amp;ltCanvas&amp;gt&lt;br /&gt;    &amp;ltRectangle x:Name="button1"&lt;br /&gt;               Width="120"&lt;br /&gt;               Height="75"&lt;br /&gt;               Canvas.Left="0"&lt;br /&gt;               Canvas.Top="30"&lt;br /&gt;               Stretch="Fill"&lt;br /&gt;               MouseEnter="javascript:ImageButtonEnter"&lt;br /&gt;               MouseLeave="javascript:ImageButtonLeave"&lt;br /&gt;               MouseLeftButtonDown="javascript:ImageButtonDown1"&lt;br /&gt;               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&amp;gt&lt;br /&gt;      &amp;ltRectangle.Fill&amp;gt&lt;br /&gt;        &amp;ltImageBrush ImageSource="images/jetski.jpg"&amp;gt&amp;lt/ImageBrush&amp;gt&lt;br /&gt;      &amp;lt/Rectangle.Fill&amp;gt&lt;br /&gt;    &amp;lt/Rectangle&amp;gt&lt;br /&gt;  &amp;lt/Canvas&amp;gt&lt;br /&gt;  &amp;ltCanvas&amp;gt&lt;br /&gt;    &amp;ltRectangle x:Name="button2"&lt;br /&gt;               Width="120"&lt;br /&gt;               Height="75"&lt;br /&gt;               Canvas.Left="0"&lt;br /&gt;               Canvas.Top="60"&lt;br /&gt;               Stretch="Fill" &lt;br /&gt;               MouseEnter="javascript:ImageButtonEnter"&lt;br /&gt;               MouseLeave="javascript:ImageButtonLeave"&lt;br /&gt;               MouseLeftButtonDown="javascript:ImageButtonDown2"&lt;br /&gt;               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&amp;gt&lt;br /&gt;      &amp;ltRectangle.Fill&amp;gt&lt;br /&gt;        &amp;ltImageBrush ImageSource="images/soundbarrier.jpg"&amp;gt&amp;lt/ImageBrush&amp;gt&lt;br /&gt;      &amp;lt/Rectangle.Fill&amp;gt&lt;br /&gt;    &amp;lt/Rectangle&amp;gt&lt;br /&gt;  &amp;lt/Canvas&amp;gt&lt;/pre&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;The JavaScript code will also need to be created using simalar techniques.   See the &lt;a href="http://trackerrealm.com/blogs/2007/04/code-creator-c-based-mini-php.html"&gt;CodeCreator Blog posting&lt;/a&gt; for more information.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://barcamp.pbwiki.com/OttawaCamps"&gt;&lt;img src="http://barcamp.pbwiki.com/f/democamp_ottawa_presenter.gif"/&gt;&lt;br /&gt;Demonstrated at Ottawa Demo Camp&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2983611102045055811?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2983611102045055811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2983611102045055811' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2983611102045055811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2983611102045055811'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/05/using-code-creator-to-create.html' title='Using Code Creator to Create SilverLight Controls (WPF/E)'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-3884396248956496515</id><published>2007-04-28T09:28:00.000-04:00</published><updated>2007-05-09T07:42:30.021-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><title type='text'>Code Creator - a C# based mini PHP</title><content type='html'>Creating code dyanamically is a very strong requirement for any advanced programming tasks.  Code Creator source will be available in the near future.  &lt;a href="http://trackerrealm.com/blogs/CodeCreatorZip/image.zip"&gt;The software and data files&lt;/a&gt; presented at Demo Camp on Apr 30th can be found here.  A &lt;a href="http://www.trackerrealm.com/blogs/CodeCreator/CC.ppt"&gt;PowerPoint presentation&lt;/a&gt; that is also available.&lt;br /&gt;&lt;br /&gt;Also see &lt;a href="http://trackerrealm.com/blogs/2007/05/using-code-creator-to-create.html"&gt;Creating as SilverLight Control with CodeCreator&lt;/a&gt; for an example on using CodeCreator.&lt;br /&gt;&lt;br /&gt;Code Creator supports the creation of almost any type of code including XML.&lt;br /&gt;Code Creator competes very well with PHP in the .net environment simply because it leverages .net's power.   Above all Code Creator is small and simple.  &lt;br /&gt;&lt;br /&gt;An example of CodeCreator creating C# code segment.&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;&lt;span lang=EN-CA style='color:#339966'&gt;// In a real system "nameUC" and "name" would get data&lt;br /&gt;// from a database or XML data file.&lt;br /&gt;// "nameUC" and "name" are &lt;br /&gt;// passed as parameters to Code Generator.&lt;br /&gt;//&lt;/span&gt;&lt;br /&gt;string[] nameUC = new string[]{"NAME", "SYSTEM", "ADMINISTRATOR"};&lt;br /&gt;string[] name = new string[] {"Name", "System", "Administrator"};&lt;br /&gt;&lt;span lang=EN-CA style='color:#339966'&gt;...&lt;br /&gt;// The next few lines of code are passed to Code Generator&lt;br /&gt;// as a string.&lt;br /&gt;//&lt;br /&gt;//&amp;ltRepeat&amp;gt  -- note that Code Creator commands are&lt;br /&gt;// hidden in comments.&lt;/span&gt;&lt;br /&gt;public const string NAME = "name"; &lt;br /&gt;&lt;span lang=EN-CA style='color:#339966'&gt;//&amp;ltReplace&amp;gtpublic const string $nameUC$ = "$name$";&amp;lt/Replace&amp;gt&lt;br /&gt;//&amp;lt/Repeat&amp;gt&lt;/span&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;Will result in code be generated below:&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;public const string NAME = "Name";&lt;br /&gt;public const string SYSTEM = "System";&lt;br /&gt;public const string ADMINISTRATOR = "Administrator";&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;&lt;strong&gt;CodeCreator Uses&lt;/strong&gt;&lt;br /&gt;-Create typed classes from a database schema&lt;br /&gt;---example C# classes where enumerations, string constants and properties are created dynamically&lt;br /&gt;-Build powerful HTML controls easily&lt;br /&gt;---example create JavaScript and HTML code dynamically from CLR objects&lt;br /&gt;-Build WPE/E (SilverLight) controls&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Code Creator details: &lt;/strong&gt;&lt;br /&gt;-          less than 1000 lines of C# code &lt;br /&gt;-          few basic functions – Replace, Repeat, Declare, Evaluate&lt;br /&gt;-          Accepts data from XML or CLR objects (very much like WPF).&lt;br /&gt;-          Built primarily on&lt;br /&gt;--&gt;       “StringBuilder” class.&lt;br /&gt;--&gt;       Tiny Interpreter class.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;       Tiny Interpreter (C#)&lt;/strong&gt;&lt;br /&gt;-        Implementation of “Gang of 4” interpreter class&lt;br /&gt;-        Uses 80 line method employing REGEX to tokenize string &lt;br /&gt;-        Less 1000 lines of code&lt;br /&gt;-        Evaluates mathematical and logical expressions&lt;br /&gt;-        Example:&lt;pre&gt;&lt;em&gt;&lt;strong&gt;&lt;span lang=EN-CA style='color:#339966'&gt;&amp;ltEvaluate&amp;gtXCoord = XCoord + (30 * Height);&amp;lt/Evaluate&amp;gt&lt;/span&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://barcamp.pbwiki.com/OttawaCamps"&gt;&lt;img src="http://barcamp.pbwiki.com/f/democamp_ottawa_presenter.gif"/&gt;&lt;br /&gt;Demonstrated at Ottawa Demo Camp&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-3884396248956496515?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/3884396248956496515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=3884396248956496515' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3884396248956496515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3884396248956496515'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/04/code-creator-c-based-mini-php.html' title='Code Creator - a C# based mini PHP'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-7400645485018259745</id><published>2007-04-11T10:06:00.000-04:00</published><updated>2007-04-28T10:11:29.290-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><category scheme='http://www.blogger.com/atom/ns#' term='CodingGuideline C#'/><title type='text'>Top 10 Coding Guidelines for C#</title><content type='html'>Here is a set of coding guidelines that we use to generate code. Using these guidelines we strive to build software that improves the 'able' criteria such as maintainable, readable, reliable, expandable, reusable, etc. The measurement of these criteria is somewhat subjective.&lt;br /&gt;&lt;br /&gt;It should be noted that the biggest factors that impact the 'able' criteria are made by selecting C#, .net and Visual Studio development environment. The guidelines merely refine the results.&lt;br /&gt;&lt;br /&gt;Here is out top 10 .net C# coding guidelines. &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use Object Oriented (00) principles. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use unit tests.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Avoid global (or static) properties or variables.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make extensive use of  core .net classes such as Collection and Regular Expressions&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use strong typing and avoid the use of the "object" type.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use Auto-Generated Code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use a naming convention.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use Static Methods and Constants&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use the "this" keyword.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://trackerrealm.com/blogs/2007/04/make-use-of-regions-when-developing-c.html"&gt;Use Regions to place code in Chapters and Sections&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-7400645485018259745?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/7400645485018259745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=7400645485018259745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7400645485018259745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7400645485018259745'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/04/top-10-coding-guidelines-for-c.html' title='Top 10 Coding Guidelines for C#'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-3752683539107854764</id><published>2007-04-10T17:26:00.000-04:00</published><updated>2010-06-27T11:21:36.227-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><category scheme='http://www.blogger.com/atom/ns#' term='CodingGuideline C#'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Make Use of #regions When Developing C# .net Code - Coding Guidlines Series</title><content type='html'>&lt;p&gt;The is part of a .net &lt;a href="http://trackerrealm.com/blogs/2007/04/top-10-coding-guidelines-for-c.html"&gt;Coding Guidelines series &lt;/a&gt;of blog postings.     &lt;br /&gt;    &lt;br /&gt;Making code readable is an important consideration when developing and maintaining code. The single best way to make code more organized, thus more readable, is to use &amp;quot;region&amp;quot; compiler directive. Regions effectively group your code into sections and chapters. &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="580"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://www.trackerrealm.com/Blogs/CodingGuidline/noregions.JPG"&gt;&lt;img style="margin: 0px 10px 10px 0px; width: 320px; float: left; cursor: hand" title="click to enlarge" border="0" alt="click to enlarge" src="http://www.trackerrealm.com/Blogs/CodingGuidline/noregions.JPG" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="378"&gt;This is a simple example of code without the region directive. The code is all there but even with just a few lines it can be difficult to read because nothing stands out. This only gets worse when the class is hundreds or thousands lines long.          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://www.trackerrealm.com/Blogs/CodingGuidline/regions.JPG"&gt;&lt;img style="margin: 0px 10px 10px 0px; width: 320px; float: left; cursor: hand" title="click to enlarge" border="0" alt="click to enlarge" src="http://www.trackerrealm.com/Blogs/CodingGuidline/regions.JPG" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="378"&gt;Here is the same code with regions. It just looks a lot cleaner.          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://www.trackerrealm.com/Blogs/CodingGuidline/selectregion.JPG"&gt;&lt;img style="margin: 0px 10px 10px 0px; width: 320px; float: left; cursor: hand" title="click to enlarge" border="0" alt="click to enlarge" src="http://www.trackerrealm.com/Blogs/CodingGuidline/selectregion.JPG" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="378"&gt;Now when you have found the selection that you want it is simply a matter of double clicking the region tag to see the details.          &lt;br /&gt;          &lt;br /&gt;(example to be added)Even code with regions can get out hand when there are a large number of regions. Then it is time to group the regions into regions. &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;other tips:   &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/tips-to-prevent-net-memory-leaks.html"&gt;Tips to prevent memory leaks.&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://yourdotnetdesignteam.blogspot.com/2010/06/built-in-delegate-types-methods-as.html"&gt;Built-in Delegate Types - Methods as Objects&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-3752683539107854764?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/3752683539107854764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=3752683539107854764' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3752683539107854764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/3752683539107854764'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/04/make-use-of-regions-when-developing-c.html' title='Make Use of #regions When Developing C# .net Code - Coding Guidlines Series'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-7484959935306817104</id><published>2007-04-09T10:51:00.000-04:00</published><updated>2010-06-11T20:19:57.463-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><category scheme='http://www.blogger.com/atom/ns#' term='Regular Expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Tokenize a String with C# Regular Expressions</title><content type='html'>Using C# and .net regular expressions it easy to parse even the most complex string into tokens very easily.&lt;br /&gt;For example convert the following string:&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;"365 + 6 *(6.3 + Count)"&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;into something like this:&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;Token[0], Integer, "365"&lt;br /&gt;Token[1], Plus, "+"&lt;br /&gt;Token[2], Integer, "6"&lt;br /&gt;Token[3], Mulitply, "*"&lt;br /&gt;Token[4], OpenBracket, "("&lt;br /&gt;Token[5], Double, "6.3"&lt;br /&gt;Token[6], Plus, "+"&lt;br /&gt;Token[7], Variable, "Count"&lt;br /&gt;Token[8], CloseBracket, ")"&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;With out using regular expressions it becomes quite a programming exercise. With regular expressions it becomes quite simple. The regular expression technique even supports simple syntax checking for invalid characters or character sequences.&lt;br /&gt;&lt;br /&gt;Here are the steps.&lt;br /&gt;1. Define a Token helper class.&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;public class Token&lt;br /&gt;{&lt;br /&gt;   public readonly string Name;&lt;br /&gt;   public readonly string Value;&lt;br /&gt;   public Token(string name, string value)&lt;br /&gt;   {&lt;br /&gt;      Name = name;&lt;br /&gt;      Value = value;&lt;br /&gt;   } &amp;gt;&lt;br /&gt;}&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;2. Define the regular expression pattern using named groups looking something like this. &lt;pre&gt;&lt;em&gt;&lt;strong&gt;private static string pattern =&lt;br /&gt;    @"(?&amp;lt;whitespace&amp;gt;\s*)|" +&lt;br /&gt;    @"(?&amp;lt;variable&amp;gt;[a-zA-Z_$][a-zA-Z0-9_$]*)|" +&lt;br /&gt;    @"(?&amp;lt;integer&amp;gt;[0-9]+)|" +&lt;br /&gt;    @"(?&amp;lt;plus&amp;gt;\+)|" +&lt;br /&gt;    @"(?&amp;lt;minus&amp;gt;-)|" +&lt;br /&gt;    @"(?&amp;lt;multiply&amp;gt;\*)|" +&lt;br /&gt;    @"(?&amp;lt;invalid&amp;gt;[^\s]+)";&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;The regular expression explained: The round brackets"(...)" define a group that support matching a subexpression. The "?&lt;name&gt;" give the group a name. The "\s" matches on a white space character, with the "\s*" subexpression matching on zero or more whitespace characters in a row.&lt;br /&gt;Overall the pattern directs to both match on whitespace and on one of the following groups or subexpressions such as "variable", "integer". Notice the "" character (shift backslash on keyboard) after each group which is the logical 'or' in C#; however in regular expressions it is known as the 'alternation' character with each subexpression known as the alternative. When the first alternative match is found then matching stops.&lt;br /&gt;The "invalid" group will match on character string not matched by any of the other alternative groups. This supports simple syntax check.&lt;br /&gt;&lt;br /&gt;3. Generate the regular expression code.&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;    Regex regexPattern = new Regex(pattern);&lt;br /&gt;    MatchCollection matches = regexPattern.Matches("365 + 6 * Count");&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;4. Perform a "foreach" on matches to generate the tokens.&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;List&lt;token&gt; tokenList = new List&lt;token&gt;();&lt;br /&gt;foreach (Match match in matches)&lt;br /&gt;{&lt;br /&gt;   int i = 0;&lt;br /&gt;   foreach (Group group in match.Groups)&lt;br /&gt;   {&lt;br /&gt;      string matchValue = group.Value;&lt;br /&gt;      bool success = group.Success;&lt;br /&gt;      // ignore capture index 0 and 1 (general and WhiteSpace)&lt;br /&gt;      if ( success &amp;amp;&amp;amp; i &gt; 1)&lt;br /&gt;      {&lt;br /&gt;         string groupName = regexPattern.GroupNameFromNumber(i);&lt;br /&gt;         tokenList.Add(new Token(groupName , matchValue));&lt;br /&gt;      }&lt;br /&gt;      i++;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;}&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;That is all that is to it. A very small amount of code to quickly parse a string.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Note:&lt;/strong&gt; When using regular expressions it is very easy for a single character to change the meaning of a regular expression. Techniques such as code inspection rarely will reveal a problem. It is important with all code, but especially code using regular expressions, to build a good set of unit tests that exercise most, if not all, of the combinations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-7484959935306817104?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/7484959935306817104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=7484959935306817104' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7484959935306817104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/7484959935306817104'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/04/tokenize-string-with-c-regular.html' title='Tokenize a String with C# Regular Expressions'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-4006439905831494600</id><published>2007-03-29T13:31:00.000-04:00</published><updated>2007-04-11T11:42:19.331-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='C Sharp'/><title type='text'>Selecting Editable Items in an .net WPF ListBox (or ComboBox)</title><content type='html'>What could be simpler than selecting items from a WPF ListBox. You can even make the items have fancy formating using a TextBlock. If you want to allow the user to edit the ListBox items then there is a problem. This occurs when your ListBox items are editable objects, such as a TextBox. Selecting around the TextBox selects the appropriate ListBox item, but selecting the TextBox only selects the TextBox.&lt;br /&gt;&lt;br /&gt;The solution to this problem is when the TextBox is selected, to also select the ListBox item. To this you need to setup an event handler and write a few lines of C# code. You want use the "GotFocus" event since the TextBox may be selected by multiple methods such as tabbing with the keyboard or clicking with the mouse.&lt;br /&gt;&lt;br /&gt;To make things simpler you can use Expression Blend to setup the event handler and create C# shell code. To do this select the TextBox properities using Expression Blend and then select the event handlers.&lt;br /&gt;&lt;br /&gt;Here is a C# event handler for the TextBox, which is any item in ListBox for this example.&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;private void TextBox_GotFocus(object sender, RoutedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    TextBox tb = sender as TextBox;&lt;br /&gt;    if (tb == null) return;&lt;br /&gt;    if (tb.DataContext == null) return;&lt;br /&gt;    this.listBoxDataItems.SelectedItem = tb.DataContext;&lt;br /&gt;}&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;&lt;br /&gt;Where the ListBox is defined as&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;&lt;listbox itemtemplate="{DynamicResource VariableItemEditTemplate }"&gt;&lt;br /&gt;     ItemsSource="{Binding Path=CodeCreatorData}"&lt;br /&gt;     x:Name="listBoxDataItems" /&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/pre&gt;&lt;br /&gt;with a template like this&lt;br /&gt;&lt;pre&gt;&lt;em&gt;&lt;strong&gt;&lt;datatemplate key="VariableItemEditTemplate"&gt;&lt;br /&gt;   &lt;textbox text="{Binding Path=Name}" width="Auto"&lt;br /&gt;       GotFocus="TextBox_GotFocus"/&gt;&lt;br /&gt;&lt;/datatemplate&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/em&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-4006439905831494600?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/4006439905831494600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=4006439905831494600' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4006439905831494600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/4006439905831494600'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/03/selecting-items-in-net-wpf-listbox-or.html' title='Selecting Editable Items in an .net WPF ListBox (or ComboBox)'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-8281862161048733389</id><published>2007-03-16T12:13:00.000-04:00</published><updated>2010-06-11T20:20:29.913-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='Jetfire'/><title type='text'>What is Workflow EcoSystem?</title><content type='html'>Workflows have recently gained a lot attention since Microsoft introduced a workflow engine as part of .Net release 3.0 and have workflows integrated with Office 2007 and SharePoint. Workflows as mechanism to automate applications have been around for while. We have had a Workflow engine for several years.&lt;br /&gt;What is clear is that to use workflows as sucessful automation tool a complete ecosystem is required. Our view is that a complete workflow ecosystem consists of 5 key components.&lt;br /&gt;5 Key Components of a Workflow Ecosystem &lt;ol&gt;&lt;li&gt;Workflow Designer&lt;/li&gt;&lt;li&gt;User Interface&lt;/li&gt;&lt;li&gt;Data Persistence Layer&lt;/li&gt;&lt;li&gt;Data Report Generator&lt;/li&gt;&lt;li&gt;Workflow Engine&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;A white paper, &lt;a href="http://www.trackerrealm.com/Blogs/Workflow/Attributes%20of%20a%20Complete%20Workflow%20Eco.htm"&gt;Attributes of a Complete Workflow Eco-System&lt;/a&gt;, has been put together that describes what attributes are required of each of the key components.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-8281862161048733389?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/8281862161048733389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=8281862161048733389' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8281862161048733389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/8281862161048733389'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/03/what-is-workflow-ecosystem_16.html' title='What is Workflow EcoSystem?'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-2885386514322618835</id><published>2007-03-16T11:52:00.000-04:00</published><updated>2008-10-25T10:38:45.489-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SilverLight'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><title type='text'>Using SilverLight (WPF/E) creates clear images</title><content type='html'>Remember migrating from .net 2.0 from 1.1 at your ISP? Our ISP created a separate server with .net 2.0 libraries and selected clients moved their applications to that server. Of course, if the application included Web Service, Web Pages and Windows Client, ALL code had to be converted to .net 2.0 before it was deployed.&lt;br /&gt;&lt;br /&gt;Migrating to Microsoft .net 3.0 is MUCH simpler, because the ASPX server is still a ASP.net 2.0 Server. Of course, our ISP seems to be taking a 'measured' approach. But does that stop us from playing with .net 3.0 and wanting to show our endeavors? Of course not.&lt;br /&gt;&lt;br /&gt;Do you get annoyed when images are not clear on web pages because of rescaling? The really cool facet of .net 3.0 is Managed Code directly accessing un-managed code, namely DirectX. Use XAML - a new, mark-up language to build user interfaces with.net 3.0 libraries. Images can be displayed with amazing clarity.&lt;br /&gt;&lt;br /&gt;Using Microsoft &lt;a href="http://www.microsoft.com/products/expression/en/expression-design/default.mspx"&gt;Expression Design&lt;/a&gt;, we created a simple &lt;a href="http://www.trackerrealm.com/blogs/WPFEControls/images.htm"&gt;WPF/E image control&lt;/a&gt; that displays thumbnails and allows the user to select an image that scales. Look at the clarity of this image. So how did this code reach the web?&lt;br /&gt;1. Post code to ISP. Problem - XAML file type not recognized and hence the control did not display at all.&lt;br /&gt;2. Change XAML file type to XML file type - control now displays!&lt;br /&gt;3. Login to ISP technical page and chat with support staff. Ask them to add the XAML file type to the web server (use same characteristics as XML file type).&lt;br /&gt;4. WPF/E control now displays in a web page from our ISP.&lt;br /&gt;5. Go to 'virgin' PC (one that hasn't used .net 3.0). Open web page with WPF/E control. Because this control is a WPF/E control, the page displays a note that the WPF/E plugin needs to be downloaded. Click to download.&lt;br /&gt;6. View fantastic WPF/E image selector control with great image clarity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-2885386514322618835?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://trackerrealm.com' title='Using SilverLight (WPF/E) creates clear images'/><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/2885386514322618835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=2885386514322618835' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2885386514322618835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/2885386514322618835'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/03/recognizing-xaml-file-type-creates.html' title='Using SilverLight (WPF/E) creates clear images'/><author><name>Charles</name><uri>http://www.blogger.com/profile/05077026930393604354</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-6646766968459200952</id><published>2007-03-15T16:34:00.000-04:00</published><updated>2007-03-15T16:57:06.081-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.net'/><category scheme='http://www.blogger.com/atom/ns#' term='SharePoint'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>SharePoint and ASP.Net Web Parts Suite</title><content type='html'>&lt;a href="http://products.trackerrealm.com/WebParts/Default.aspx?page=Home"&gt;Our Web Parts Suite&lt;/a&gt; is now here. It is free and will remain free. The big news is that it works with both SharePoint and ASP.net 2.0. In fact our web site uses these web parts.&lt;br /&gt;&lt;br /&gt;Download the suite and tells what you think. We plan on enhancing the suite both with more parts and features.&lt;br /&gt;&lt;br /&gt;If you want the source code or would like custom web parts built, well that's not free. Somebody has to pay the bills.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-6646766968459200952?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/6646766968459200952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=6646766968459200952' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6646766968459200952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/6646766968459200952'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/03/sharepoint-and-aspnet-web-parts-suite.html' title='SharePoint and ASP.Net Web Parts Suite'/><author><name>Blogs TrackerRealm</name><uri>http://www.blogger.com/profile/00331907846645255860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5878313286923455019.post-1550702312648468525</id><published>2007-02-27T12:29:00.000-05:00</published><updated>2008-10-25T10:36:32.783-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF/E'/><category scheme='http://www.blogger.com/atom/ns#' term='SilverLight'/><title type='text'>WPF/E Controls (SilverLight Controls)</title><content type='html'>Lately we have looking at creating a better forms environment for our work with workflows and SharePoint. XML forms look interesting, but have a number of drawbacks. Recently we have been evaluating WPF/E for use as a Forms package base.&lt;br /&gt;&lt;br /&gt;Here are some controls that we have created as part of a science project. The code is very crude, doesn't cover all the conditions, but you get the idea of how it can be done.&lt;br /&gt;&lt;br /&gt;Short list of WPF/E (SilverLight) example controls.&lt;br /&gt;&lt;a href="http://www.trackerrealm.com/blogs/WPFEControls/images.htm"&gt;ListBox&lt;/a&gt; - enhanced using a card shuffle style list. Shows some of the power WPF/E. Mouse over the thumbnails on the left to view animation.&lt;br /&gt;&lt;a href="http://www.trackerrealm.com/blogs/WPFEControls/DropDownPlain.htm"&gt;ComboBox&lt;/a&gt; - Hard coded number of list items.&lt;br /&gt;&lt;a href="http://www.trackerrealm.com/blogs/WPFEControls/textbox.htm"&gt;TextBox&lt;/a&gt; - Javascript code for this control only covers some of the conditions. Required is the ability to cut, paste, highlight and drag. In addition the cursor positioning (which is absolute and relative to the root canvas) needs to take into the account the scaling used, which could be difficult if this control is embedded in other controls each its own scaling factor.&lt;br /&gt;&lt;br /&gt;The above controls are stand alone. For production they would need some sort of framework to work within (there are some examples at the Microsoft blog site).&lt;br /&gt;&lt;br /&gt;Our conclusion (&lt;a href="http://trackerrealm.com/blogs/foils/wpfexbap.htm"&gt;see foil&lt;/a&gt;) is to work with WPF/XBAP sacrificing some universality for speed of implementation. In the meantime we will continue look at putting together some controls and a framework as a continuation of this science project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5878313286923455019-1550702312648468525?l=yourdotnetdesignteam.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yourdotnetdesignteam.blogspot.com/feeds/1550702312648468525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5878313286923455019&amp;postID=1550702312648468525' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1550702312648468525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5878313286923455019/posts/default/1550702312648468525'/><link rel='alternate' type='text/html' href='http://yourdotnetdesignteam.blogspot.com/2007/02/wpfe-controls_27.html' title='WPF/E Controls (SilverLight Controls)'/><author><name>John Hansen</name><uri>http://www.blogger.com/profile/01859123979998092677</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_WqqRGkoDIG0/TCSxPcXxk0I/AAAAAAAAABU/Kxw_iKWZ3CE/S220/johnportrait2.jpg'/></author><thr:total>1</thr:total></entry></feed>
