<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-5878313286923455019</atom:id><lastBuildDate>Wed, 10 Mar 2010 13:42:32 +0000</lastBuildDate><title>your .net design team</title><description></description><link>http://trackerrealm.com/blogs/</link><managingEditor>noreply@blogger.com (Blogs TrackerRealm)</managingEditor><generator>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-1086593195292194594</guid><pubDate>Wed, 18 Nov 2009 20:50:00 +0000</pubDate><atom:updated>2009-11-18T12:50:23.409-08:00</atom:updated><title>ODNC Luncheon Seminar Series Presents: Test Driven Design (aRealWorldExample)</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2009/11/odnc-luncheon-seminar-series-presents.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-1270963699750175722</guid><pubDate>Wed, 29 Apr 2009 20:22:00 +0000</pubDate><atom:updated>2009-04-30T08:39:49.082-07:00</atom:updated><title>Jetfire – Maybe we should have called it DC#</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2009/04/jetfire-maybe-we-should-have-called-it.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-4954872586449857041</guid><pubDate>Fri, 17 Apr 2009 16:10:00 +0000</pubDate><atom:updated>2009-04-29T13:23:42.814-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Modeling a Workflow in Software</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2009/04/modeling-workflow-in-software.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-4581170875670356113</guid><pubDate>Sun, 22 Mar 2009 14:53:00 +0000</pubDate><atom:updated>2009-03-24T06:23:47.286-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Form Maker debut</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2009/03/form-maker-debut.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-2224540894961763661</guid><pubDate>Sun, 22 Mar 2009 14:51:00 +0000</pubDate><atom:updated>2009-03-24T06:23:47.286-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Supporting Quality Processes</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2009/03/why-scripting-language.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-6664412275562692597</guid><pubDate>Sun, 22 Mar 2009 14:33:00 +0000</pubDate><atom:updated>2009-03-24T06:23:47.286-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Writing programs for the workflow domain</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2009/03/what-domain.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-8758015768402269586</guid><pubDate>Tue, 17 Mar 2009 18:20:00 +0000</pubDate><atom:updated>2009-03-17T14:21:09.284-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>persistence</category><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Why a Domain Specific Language is better than a Framework!</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2009/03/why-domain-specific-language-is-better.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-2404838627295820545</guid><pubDate>Wed, 12 Nov 2008 16:38:00 +0000</pubDate><atom:updated>2009-01-14T09:03:56.470-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Policy based Management with Jetfire</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/11/policy-based-management-with-jetfire.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-5976520529078389185</guid><pubDate>Wed, 12 Nov 2008 01:09:00 +0000</pubDate><atom:updated>2008-11-17T19:48:52.242-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Visual Studio</category><title>Navigating in Visual Studio</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/11/navigating-in-visual-studio_11.html</link><author>noreply@blogger.com (SW)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-2579975746904881303</guid><pubDate>Wed, 29 Oct 2008 01:33:00 +0000</pubDate><atom:updated>2008-11-12T05:07:41.097-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>ASP.net</category><category domain='http://www.blogger.com/atom/ns#'>Web Parts</category><title>Building a Color Editor using COR</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/10/building-color-editor-using-cor.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-8342003154752077638</guid><pubDate>Sun, 19 Oct 2008 22:27:00 +0000</pubDate><atom:updated>2008-10-29T05:38:57.352-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>ASP.net</category><category domain='http://www.blogger.com/atom/ns#'>Web Parts</category><title>FAQs for COR - A Web Site Building Tool</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/10/faq-cor-web-site-building-tool.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-812594001727752949</guid><pubDate>Sun, 12 Oct 2008 17:16:00 +0000</pubDate><atom:updated>2008-10-25T08:01:03.882-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Visual Studio</category><title>Displaying Line Numbers in Visual Studio</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/10/displaying-line-numbers-in-visual.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-3536081575202687171</guid><pubDate>Sun, 28 Sep 2008 18:21:00 +0000</pubDate><atom:updated>2008-10-05T13:56:35.435-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>ASP.net</category><title>Adding ASP.NET Controls programmatically</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/09/adding-controls-programmatically.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-868658376386867306</guid><pubDate>Sun, 28 Sep 2008 13:17:00 +0000</pubDate><atom:updated>2008-10-13T06:38:46.845-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>ASP.net</category><title>The Life Cycle of ASP.NET Controls</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/09/life-cycle-of-aspnet-controls_28.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-3540767309800789684</guid><pubDate>Sat, 26 Jul 2008 19:41:00 +0000</pubDate><atom:updated>2008-10-25T07:56:04.239-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Quiz made easy</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/07/quiz-made-easy.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-3104759246807625325</guid><pubDate>Fri, 04 Jul 2008 14:44:00 +0000</pubDate><atom:updated>2008-07-04T09:40:07.405-07:00</atom:updated><title>Kudos to screwturn wiki </title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/07/kudos-to-screwturn-wiki.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-8148835155824195376</guid><pubDate>Thu, 03 Jul 2008 20:17:00 +0000</pubDate><atom:updated>2008-07-03T13:23:51.204-07:00</atom:updated><title>New Blog Editor</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/07/new-blog-editor.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-944403322990242579</guid><pubDate>Wed, 25 Jun 2008 22:05:00 +0000</pubDate><atom:updated>2008-06-26T11:44:31.883-07:00</atom:updated><title>ADO.Net: The Good, The Bad and The Ugly</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/06/adonet-good-bad-and-ugly.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-8610138103043179566</guid><pubDate>Fri, 20 Jun 2008 15:54:00 +0000</pubDate><atom:updated>2008-06-20T12:27:20.020-07:00</atom:updated><title>Open Source License Favorites</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/06/open-source-license-favorites.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-850956826707601874</guid><pubDate>Thu, 19 Jun 2008 20:22:00 +0000</pubDate><atom:updated>2008-07-07T08:45:53.085-07:00</atom:updated><title>COR - Why make it free?</title><description>&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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/06/cor-why-make-it-free.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-3843697255830742451</guid><pubDate>Thu, 12 Jun 2008 18:57:00 +0000</pubDate><atom:updated>2008-06-25T09:43:51.438-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>persistence</category><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Hello World with Jetfire</title><description>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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2008/06/hello-world-with-jetfire.html</link><author>noreply@blogger.com (John Hansen)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-2474923942382862691</guid><pubDate>Sat, 29 Sep 2007 01:51:00 +0000</pubDate><atom:updated>2008-04-17T13:52:14.701-07:00</atom:updated><title>Auto-Display for Workflows</title><description>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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2007/09/auto-display-for-workflows.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-254321682422690853</guid><pubDate>Sat, 29 Sep 2007 01:24:00 +0000</pubDate><atom:updated>2007-09-28T18:48:45.300-07:00</atom:updated><title>Silverlight 1.0 Released</title><description>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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2007/09/silverlight-10-released.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-1976309695990379917</guid><pubDate>Wed, 26 Sep 2007 22:03:00 +0000</pubDate><atom:updated>2008-10-25T07:59:33.657-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Jetfire is born</title><description>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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2007/09/jetfire-is-born.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5878313286923455019.post-245404386475310051</guid><pubDate>Wed, 26 Sep 2007 21:09:00 +0000</pubDate><atom:updated>2008-10-25T07:59:13.938-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Jetfire</category><title>Jetfire debut at Ottawa Demo Camp</title><description>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=trackerrealm.com%2Fblogs%2Findex.html' alt='' /&gt;&lt;/div&gt;</description><link>http://trackerrealm.com/blogs/2007/09/jetfire-debut-at-ottawa-demo-camp.html</link><author>noreply@blogger.com (Charles)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item></channel></rss>