Using Workflow Foundation Rules Engine beyond Workflow ...

Most people are aware that Workflow Foundation is a massively powerful flexible toolset to allow you to build workflow based applications.  In true golden hammer style, once you have used it you will be surprised just how many problems look like they need to be solved with workflow!  What you may have missed is that part of the delivery is a very powerful rules engine that can easily be used outside of workflow applications.

In an effort to keep this post short I will keep it very simple and demonstrate how easy it is to use the rules engine outside of the context of workflow activities.

Before you start make sure you have .NET 3.0 installed (http://www.microsoft.com/downloads/details.aspx?FamilyID=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en), installed the Visual Studio 2005 extensions for WF (http://www.microsoft.com/downloads/details.aspx?familyid=5D61409E-1FA3-48CF-8023-E8F38E709BA6&displaylang=en) and finally make sure you have read the excellent introduction to the rules engine by Jurgen Willis http://msdn2.microsoft.com/en-us/library/aa480193.aspx.

The simplest way to create a RuleSet is to use the RuleSetDialog in the System.Workflow.Activities.Rules.Design namespace to create and edit a RuleSet. The dialog is supplied a context object on construction - basically the type is reflected to see what is available for the intellisense on the editor dialog.  To use the RuleSetDialog you need to reference the System.Workflow.Activities and System.Workflow.ComponentModel assemblies.

RuleSetDialogCode

The RuleSetDialog allows you to define rules which are constructs similar to a basic If-Then-Else programming structure, with the condition and actions defined in an expression language based on the CodeDom model (read Jurgens article for more description).  Basically you can access properties and methods on you context object, and static methods on any class referenced within the host assembly.

RuleSetDialog

The RuleSet is serialisable (to XAML), so dead easy to create persist and reload collections of rules - you can work this bit out for yourself.

To execute a RuleSet you use the RuleEngine in the System.Workflow.Activities.Rules namespace.  You supply it an instance of your object and then Execute and off it goes.

RuleEngine

As you can see in this somewhat traditional bogus example, the rule checks for a literal value on a property of the context object, setting it to a different value if true.

Bogus though the example is, it doesn't take much imagination to picture how the rules engine can be harnessed to create massively powerful and extensible apps - with rules persisted outside of the app and editable by users that are able to operate on and affect data within your objects!  Get me a nail I have a new hammer...

Draggy bags...

You know those bags with wheels and handles! Hate them.  Crowded places like railway stations and airports where we are all herded through like sheep are annoying enough without having to trip over the little draggy bags - suitcases are easy to avoid, but the little ones just get under your feet!!

CruiseControl.NET installation in 7 easy steps

I often find people are intimidated by CruiseControl.NET. One of the phrases I have heard before is that it is "only really sensible for new projects" - the explanation behind this usually being that it is too difficult to set up for existing solutions.  This guide is designed to show how easy it is to get started on any .NET solution, no matter where in the development phase. 

The primary goal of this guide is simply to create a nightly build of a project maintained in Visual SourceSafe 2005 with CruiseControl.NET - one of the simplest configurations you can imagine. Those of you doing continuous integration will already recognise this as the first in many baby step's that can be taken to improve existing process using CruiseControl.NET (hopefully the subject of a future article). Those of you who want more information on what continuous integration is and can do to help may find these articles useful:

http://www.martinfowler.com/articles/continuousIntegration.html

http://confluence.public.thoughtworks.org/display/CCNET/What+is+Continuous+Integration

Step 1 is to download and install the CruiseControl.NET application from http://sourceforge.net/projects/ccnet/ - pretty straight forward!  The version dealt with in the post is 1.3 which was released 21/06/2007.

Step 2 is to get the project(s) buildable using MSBuild from the command line, this is just a simple check to make sure the projects work! eg:

	msbuild c:\test\app.sln /t:Clean /p:Configuration=Debug
	

Step 3 create a VSS user specifically for CruiseControl.NET to log in as.

Step 4 configure the ccnet.config file which is found in the installation directory (default Program Files\CruiseControl.NET\server).  Simple config will require the a project with sourcecontrol section, an interval trigger and an msbuild, eg:

<cruisecontrol>
  <project name="TestCCNET">
    <sourcecontrol type="vss" autoGetSource="true" applyLabel="true">
      <executable>E:\Program Files\Microsoft Visual SourceSafe\ss.exe</executable>
      <project>$/TestProject</project>
      <username>ccnet</username>
      <password>ccnet</password>
      <ssdir>e:\vss\</ssdir>
      <workingDirectory>E:\work\LocalVSS\TestProject</workingDirectory>
      <cleanCopy>true</cleanCopy>
    </sourcecontrol>
    <triggers>
      <intervalTrigger seconds="60" />
    </triggers>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>E:\work\LocalVSS\TestProject</workingDirectory>
        <projectFile>TestProject.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
        <targets>Build</targets>
        <timeout>15</timeout>
        <logger/>
      </msbuild>
     </tasks>
    <publishers>
      <xmllogger />
    </publishers>
  </project>
</cruisecontrol>

Don't be frightened - when you actually look at it - there is very little required, just the source safe details and solution location!  Note that we have set the build interval to 60 seconds - this will allow us to test the configuration easily in the next step.

Step 5 download the XML Logger for MSBuild from http://ccnetlive.thoughtworks.com/MSBuildXmlLogger%2DBuilds/ and copy to the the project workingDirectory (in the example above this is set to E:\work\LocalVSS\TestProject). This logger is used by CruiseControl as described in http://confluence.public.thoughtworks.org/display/CCNET/Using+CruiseControl.NET+with+MSBuild.

Step 6 is to check the configuration setting using the command line tool.  The ccnet.exe command line tool can be found in the server directory beneath the install directory (default Program Files\CruiseControl.NET\server).  The console will run the settings and attempt the build every 60 seconds (as configured previously).  The console output is good and it should not take you long to get a basic configuration like the example above working.

You can use the Web Dashboard to force through a build (so you don't need to make a change in SourceSafe!). The Web Dashboard will be available at http://server/ccnet and the Force button is available under the admin header for each server.

Step 7 finally change the ccnet.config to replace the 60 second interval trigger with a schedule trigger eg:

<scheduleTrigger time="23:30" buildCondition="ForceBuild" name="Scheduled">
</scheduleTrigger>

Which again is fairly straight forward and will run the build every day at 2330.

So that's it CruiseControl.NET up and running to run nightly builds in 7 steps! You can now use the service rather than the command line to listen for builds, and you can use the web dashboard on the CruiseControl.NET server (http://server/ccnet) to see status of builds and force builds (when the service is running).

Clearly there is loads more that CruiseControl.NET can do (notably run your unit tests) all of which you can find using the ThoughtWorks documentation site

http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET

Debugging ASP in Visual Studio 2005

I recently had to go back in time, and debug some traditional/classic ASP.  The fact that the code was relatively nasty is pretty much irrelevant, having the capability to debug and edit in my familiar Visual Studio 2005 IDE made the job a little easier to bear! Here are the steps to enable ASP debugging in studio...

Firstly you need to Enable Server Side ASP script Debugging in IIS - this can be done at the web site level or at the virtual directly level.  For the web site go to the Home Directory Tab on properties page, and for the Virtual Directory go to the Virtual Directly tab on the properties page.  From this tab select the Configuration button under Application Settings.  On the Configuration screen select the Debugging tab and check the Enable server-side ASP script debugging.

The quick way to get to the point of debugging with all code in the IDE is to open the Web site in Visual Studio (File, Open, Web Site).

If you are using server side JavaScript then you can use the debugger statement in code to force debugging - you are offered the choice of debug tools...  Or you can attach to the running process using Debug Attach to Process.  On XP the ASP process runs under a process dllhost.exe under the IWAM user.  Clearly you need to ensure you attach to the correct process, fortunately the IDE gives a nice visual warning if you get the wrong one.

InvalidProcess

Either way you do it you will be shown a warning when attaching to the process

AttachProcessMessage

And once you attach you can step through the code as normal!

In the code I was looking at there was another interesting feature.  At some point during the difficult and painful life of this product the page Language had managed to get set to JScript.Encode (even though the code was no longer encrypted) which blocks debugging.