<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Stephen Kaufman's WebLog : WF</title><link>http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx</link><description>Tags: WF</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>AppFabric and BizTalk</title><link>http://blogs.msdn.com/skaufman/archive/2009/11/23/appfabric-and-biztalk.aspx</link><pubDate>Tue, 24 Nov 2009 05:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9927727</guid><dc:creator>skaufman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/9927727.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=9927727</wfw:commentRss><description>&lt;P&gt;There have been lots of questions lately about AppFabric (code named Dublin). These questions have centered around why Microsoft needs another middle tier solution and will AppFabric replace BizTalk.&lt;/P&gt;
&lt;P&gt;Lets take a look at these questions as well as two additional questions; What is AppFabric and why does Microsoft need another middle tier solution? First, AppFabric is a distributed application server. To answer the other questions, we need to go in a little more depth. &lt;/P&gt;
&lt;P&gt;Before .NET was released, developers working with the Microsoft technologies used COM+ to host their middle tier objects. Back then, when we needed to scale out our object oriented and object based applications we created middle tier code libraries and ‘hosted’ them in COM+. The COM+ host provided instance management (just-in-time activation), role-based security, automated transaction management as well as better memory and processor management, distributed transactions and a number of other services.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;When .NET was introduced, we moved away from COM components and also moved away from using COM+ as a hosting model. This left a vacuum that so far had gone unfilled. &lt;/P&gt;
&lt;P&gt;In attempts to fill this vacuum, individual developers had to create their own hosts. These hosts typically were Windows Services. However, these services usually didn’t include multi threading, scale out capabilities, tracking, monitoring, etc. – the types of functionality that has been in BizTalk for years. As Microsoft looked at BizTalk, as well as the .NET Framework, it was determined that there are many great features in BizTalk that if a scaled down version was available it would address gaps in the framework. Thus AppFabric was born.&lt;/P&gt;
&lt;P&gt;For .NET developers writing applications using WCF and WF, AppFabric will fill the middle tier hosting vacuum. AppFabric will provide the host and will provide scalability and support for building out your middle tier application components. It also will simplify deployment, configuration, management and scalability of composite applications. The goal of AppFabric is to provide a server infrastructure, on which business logic developed in WF can be executed and exposed via WCF endpoints, without the need to design, develop, and support the infrastructural code.&lt;/P&gt;
&lt;P&gt;The next question I hear is will AppFabric replace BizTalk? The answer is very clearly no. &lt;/P&gt;
&lt;P&gt;AppFabric should be used when your architecture calls for an application level code-first object based approach. This is the same approach that is used by WF and WCF programming models and is the one that can be hosted in AppFabric and the additional functionality that AppFabric provides. AppFabric will provide a number of management and scalability features through IIS and WAS to provide the server infrastructure without the need to write the plumbing as you did before. This is a different approach than that of the XML Schema first approach that is used in BizTalk. &lt;/P&gt;
&lt;P&gt;Use BizTalk when your architecture calls for an enterprise level message based approach. Use BizTalk when you need to isolate disparate systems that need to be connected. In point-to-point integrations, changes made to the provider system can have a profound impact on the consuming application. BizTalk natively provides a hub-based integration model which eases this burden and allows organizations to provide business services that are isolated from the impact of changes made to the systems and processes on which these services are based. This is achieved through the use of separate schemas, and the associated ability to easily develop message transformation logic using BizTalk’s Mapper tool. Use BizTalk if you have business-to-business requirements and need to integrate using technologies such as EDI, SWIFT, RosettaNet, AS2 or HL7.&lt;/P&gt;
&lt;P&gt;The reality is that businesses will utilize both of these technologies in their different application architectures. This is not an either or decision but instead a decision of where and when to use each.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Keep in mind, however, that many of the same terms are used to describe the functionality provided with both BizTalk and AppFabric. These terms are things like Content Based Routing, Correlation, long running transactions, etc. Although the terms are the same the implementation and functionality is different. With all decisions, make sure that you take a couple of minutes to look under the hood and ensure that you understand the differences. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9927727" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/BizTalk/default.aspx">BizTalk</category><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.msdn.com/skaufman/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.msdn.com/skaufman/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/skaufman/archive/tags/AppFabric/default.aspx">AppFabric</category></item><item><title>Comparing the Workflow Rules Engine to the BizTalk Business Rules Engine</title><link>http://blogs.msdn.com/skaufman/archive/2007/03/20/comparing-the-workflow-rules-engine-to-the-biztalk-business-rules-engine.aspx</link><pubDate>Wed, 21 Mar 2007 07:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1923134</guid><dc:creator>skaufman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/1923134.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=1923134</wfw:commentRss><description>&lt;P&gt;Back in November I delivered a presentation to the Twin Cities BizTalk User Group titled 'Rule Engines: Workflow Rules vs. BizTalk Rules'.&lt;/P&gt;
&lt;P&gt;Since then I have been working with the Rules Team in Redmond and with their input I have updated and added content to that presentation.&amp;nbsp; Hopefully the &lt;A class=a href="http://mnbiztalk.com/Presentations/TwinCitiesBizTalkUserGrup%20-%20Rule%20Engines.ppt" mce_href="http://mnbiztalk.com/Presentations/TwinCitiesBizTalkUserGrup%20-%20Rule%20Engines.ppt"&gt;presentation&lt;/A&gt; will help you when you get questions about how the Workflow Rules compare and relate to the BizTalk Rules Engine.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1923134" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/BizTalk/default.aspx">BizTalk</category><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category></item><item><title>Using the WF rules to iterate over a collection</title><link>http://blogs.msdn.com/skaufman/archive/2006/11/08/using-the-wf-rules-to-iterate-over-a-collection.aspx</link><pubDate>Wed, 08 Nov 2006 23:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1039938</guid><dc:creator>skaufman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/1039938.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=1039938</wfw:commentRss><description>I thought I understood how the WF Rules iterated over a collection.&amp;nbsp; Isn't that always how it goes - you really prove it to yourself when you can explain it to someone else.&amp;nbsp; Well, I started to explain how I thought it worked and this person started asking questions and I soon realized that I was no longer sure I understood it.&amp;nbsp; After a bit of research and with my newly obtained understanding I tried to explain it again and it actually made sense. 
&lt;P&gt;So, I have decided to blog about this since I am sure that others will most likely need to do this and may even need to explain it to someone else.&lt;/P&gt;
&lt;P&gt;During my research I found the MSDN article titled &lt;A href="http://msdn2.microsoft.com/en-us/library/aa480193.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa480193.aspx"&gt;Introduction to the Windows Workflow Foundation Rules Engine&lt;/A&gt; which had a little blurb towards the bottom titled Collection Processing which I found to be a good start.&amp;nbsp; I also found Matt Winkle's &lt;A href="http://blogs.msdn.com/mwinkle/archive/2006/09/08/746929.aspx" mce_href="http://blogs.msdn.com/mwinkle/archive/2006/09/08/746929.aspx"&gt;blog entry&lt;/A&gt; which had an &lt;A href="http://wf.netfx3.com/files/folders/rules_samples/entry5609.aspx" mce_href="http://wf.netfx3.com/files/folders/rules_samples/entry5609.aspx"&gt;example&lt;/A&gt; that he put on the Workflow Community Site.&amp;nbsp; It was this example that really solidified it for me.&lt;/P&gt;
&lt;P&gt;he had created 4 rules&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Rule 1&lt;/STRONG&gt;: Initialize with a priority of 2&lt;/P&gt;
&lt;P&gt;IF &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1==1&lt;BR&gt;THEN&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.enumerator = this.OrderItems.GetEnumerator()&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Rule 2&lt;/STRONG&gt;: IterateOverItems with a priority of 1&lt;/P&gt;
&lt;P&gt;IF&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.enumerator.MoveNext()&lt;BR&gt;THEN&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.currentItem = (RulesWithCollectionSample.OrderItem)this.enumerator.Current&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("Assignednumerator" + this.currentItem.Price)&lt;BR&gt;ELSE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Cosole.WriteLine("we are all done")&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Rule 3:&lt;/STRONG&gt;&amp;nbsp; IndividualItem with a priority of 0&lt;/P&gt;
&lt;P&gt;IF &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.CurrentItem != null&lt;BR&gt;THEN&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Total = this.Total + this.CurrentItem.Price * this.CurrentItem.Quantity&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("Running Total: " + this.Total.ToString())&lt;BR&gt;ELSE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("current item is null")&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Rule 4: &lt;/STRONG&gt;Finished with a priority of -1&lt;/P&gt;
&lt;P&gt;IF &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.CurrentItem == this.CurrentItem&lt;BR&gt;THEN&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("Finished True")&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Update("this/enumerator")&lt;BR&gt;ELSE&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("Finished False")&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Update("this/enumerator")&lt;/P&gt;
&lt;P&gt;In addition to these rules you also have to decorate your class with three additional properties.&amp;nbsp; &lt;/P&gt;
&lt;P class=style1&gt;First, create an enumerator property that is of type System.Collections.Generic.IEnumerator&amp;lt;T&amp;gt; or System.Collections.IEnumerator&lt;/P&gt;
&lt;P class=style1&gt;Second, create an items collection to contain your collection of items which can be of type List&amp;lt;T&amp;gt; or anything that supports IEnumerator&lt;/P&gt;
&lt;P class=style1&gt;Third, create a property to hold the current item&lt;/P&gt;
&lt;P&gt;After looking at the rules and the properties I was ready to watch it run.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Rule 1 ran first, as it should since it has the highest priority and has a condition that always returns true.&amp;nbsp; This rule populates the enumerator property backing store.&amp;nbsp; Then the rules engine looks for the rule with next highest priority, which is Rule 2.&amp;nbsp; This rule calls MoveNext on the enumerator and if it is able to move then true is returned and the THEN part of the rule runs which passes the current collection item to this.currentItem.&amp;nbsp; If MoveNext return false then the text "we are all done" will be written to the Output Window which is the last item output after all of the items in the collection has been iterated over.&lt;/P&gt;
&lt;P&gt;If the MoveNext method in Rule 2 returned true, then the rules engine again looks for the next rule with the highest priority, which is now Rule 3.&amp;nbsp; Rule 3 checks to see if there is a Current Item and if so does some work (in this case updates the total).&amp;nbsp; If the Current Item is null then we will get the text "current item is null" written to the Output Window.&amp;nbsp; However, this line is never encountered when the rules run.&lt;/P&gt;
&lt;P&gt;Finally the fourth rule is run, the condition can really be anything but it needs to be evaluated each time, which updates the engine telling it that we want to update the enumerator and force forward chaining behavior.&amp;nbsp; By doing this we are saying that the engine should look for any rules that have conditions that are reliant on the enumerator.&amp;nbsp; In this case, Rule 2 matches this and the engine loops to Rule 2 and continues to run through the rules based on priority from there.&amp;nbsp; This will then set off a loop in the rules engine moving from Rule 4 back to Rule 2, then Rule 3 and Rule 4 until the MoveNext function in Rule 2 returns false (indicating it has no more items in the collection) and the ELSE portion of the rule runs.&amp;nbsp; At this point the rules are finished processing and the control is returned back to the calling application.&lt;/P&gt;
&lt;P&gt;Hopefully this helps explain what is required to iterate over a collection as well as what is happening during the iteration process.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1039938" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category></item><item><title>Tracking Rules Execution in Windows Workflow</title><link>http://blogs.msdn.com/skaufman/archive/2006/09/15/Tracking-Rules-Execution-in-Windows-Workflow.aspx</link><pubDate>Fri, 15 Sep 2006 19:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:756154</guid><dc:creator>skaufman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/756154.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=756154</wfw:commentRss><description>&lt;p&gt;In my previous blog entry on
&lt;a href="http://blogs.msdn.com/skaufman/archive/2006/08/22/Windows_Workflow_Tracking_and_the_TrackingExtract_functionality.aspx"&gt;
Tracking and the TrackingExtract functionality&lt;/a&gt; I talked about the ability to 
track the rules that fired.&amp;nbsp; As part of this functionality I needed to 
capture the rules that fired as well as to capture an XML representation of the 
object state (this is where the TrackingExtract functionality came in) to the 
database so that reporting systems could look at the data.&amp;nbsp; When I first 
started researching to find out if this functionality existed I came across a 
great tracking
&lt;a href="http://blogs.msdn.com/moustafa/archive/2006/03/15/552214.aspx"&gt;sample&lt;/a&gt; 
on &lt;a href="http://blogs.msdn.com/moustafa"&gt;Moustafa Ahmed's&lt;/a&gt; blog.&amp;nbsp; 
This sample shows how you can use the standard tracking infrastructure to track 
the rules.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Unfortunately, the standard tracking functionality didn't do exactly what I 
was looking for.&amp;nbsp; First, the data is written to the UserEvent table in the 
UserData_Blob field and shows up as 
0x0001000000FFFFFFFF01000000000000000C020000005D53797374656D2E576F726B66......., 
which, represented the serialized object, but was somewhat unreadable. Next, I 
would need to deserialize this data and cast it to a RuleActionTrackingEvent 
type in order to work with it for reporting.&amp;nbsp; And lastly, I wanted to store 
additional data that was not part of the UserEvent table.&lt;/p&gt;
&lt;p&gt;So, I needed to augment the standard functionality with my functionality.&amp;nbsp; 
I started by creating two new tables that would live in the tracking database.&amp;nbsp; 
The first was the RulesTrackingData table and the second was the 
UserTrackingData table.&amp;nbsp; They were defined as &lt;/p&gt;
&lt;font COLOR="#0000ff"&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;CREATE TABLE &lt;/font&gt;&lt;/font&gt;
&lt;font face="Courier New" style="font-size: 9pt"&gt;[dbo].[RulesTrackingData](&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [id] [bigint] &lt;/font&gt;&lt;font face="Courier New"&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;IDENTITY&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;(1,1)
&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [ComputerName] [varchar](25) &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [ActivityType] [varchar](50) &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [InstanceID] [varchar](40) &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [EventDateTime] [varchar](50) &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [PolicyName] [varchar](50) &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [RuleName] [varchar](40) &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConditionResult] [varchar](10) &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [TrackingRecord] [varchar](500) &lt;/font&gt;&lt;font COLOR="#0000ff"&gt;
&lt;font face="Courier New" style="font-size: 9pt"&gt;NOT NULL&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;)&lt;/p&gt;
&lt;/font&gt;
&lt;p&gt;and &lt;/p&gt;
&lt;font COLOR="#0000ff"&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;CREATE TABLE &lt;/font&gt;&lt;/font&gt;
&lt;font face="Courier New"&gt;&lt;font style="font-size: 9pt"&gt;[dbo].[UserTrackingData](&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [id] [bigint] &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;IDENTITY&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;(1,1)
&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [ComputerName] [varchar](25) &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [ActivityType] [varchar](50) &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [InstanceID] [varchar](40) &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [EventDateTime] [varchar](50) &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [TrackingRecord] [varchar](500) &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;NOT NULL&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&lt;br&gt;
)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;The RulesTrackingData table will hold the tracking data for each rules that 
runs while the UserTrackingData will hold the state of the object after all of 
the rules have run.&lt;/p&gt;
&lt;p&gt;After the database had been setup it was time to work on the code.&amp;nbsp; I 
created a custom tracking service for the Workflow Runtime.&amp;nbsp; As part of my 
RuleTrackingService I created a RuleTrackingChannel class which inherited from 
TrackingChannel and a RuleTrackingService class which inherited from 
TrackingService.&amp;nbsp; To find out more about the RuleTrackingService take a 
look at my previous blog entry on
&lt;a href="http://blogs.msdn.com/skaufman/archive/2006/08/22/Windows_Workflow_Tracking_and_the_TrackingExtract_functionality.aspx"&gt;
Tracking and the TrackingExtract functionality&lt;/a&gt;.&amp;nbsp; Right now we are just 
going to focus on the RuleTrackingChannel class since this is where we get to 
grab the tracking data and write it the way we want to the database.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;So the code looked like this:&lt;/p&gt;
&lt;font SIZE="2"&gt;
&lt;blockquote&gt;
	&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;public&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;
	&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;class&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	RuleTrackingChannel : TrackingChannel&lt;br&gt;
	&lt;br&gt;
	{&lt;br&gt;
	............&lt;br&gt;
&amp;nbsp;&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;
	public&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; RuleTrackingChannel(........&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;)&lt;br&gt;
	{&lt;br&gt;
	&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt" SIZE="2"&gt;}&lt;br&gt;
	&lt;/font&gt;&lt;font COLOR="#008000" face="Courier New" style="font-size: 9pt"&gt;
	//This is what it all comes down to!&lt;br&gt;
	&lt;/font&gt;&lt;font face="Courier New"&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;protected&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;
	&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;override&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;
	&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;void&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	Send(TrackingRecord record)&lt;br&gt;
	{&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	if&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; (record &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;is&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	UserTrackingRecord)&lt;/font&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;{&lt;br&gt;
		DetermineTrackingRecordType((UserTrackingRecord)record);&lt;br&gt;
		}&lt;/font&gt;&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;}&lt;br&gt;
	&lt;br&gt;
	&lt;/font&gt;&lt;font face="Courier New"&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;private&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;
	&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;void&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	DetermineTrackingRecordType(UserTrackingRecord userTrackingRecord)&lt;br&gt;
	{&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	if&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; (userTrackingRecord.UserData &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;is&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	RuleActionTrackingEvent)&lt;/font&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;{&lt;br&gt;
		WriteRuleTrackingRecord((RuleActionTrackingEvent)userTrackingRecord.UserData, 
		userTrackingRecord);&lt;br&gt;
		}&lt;/font&gt;&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	else&lt;/font&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;&lt;font style="font-size: 9pt"&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
		WriteUserTrackingRecord(userTrackingRecord);&lt;br&gt;
		}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;&lt;font style="font-size: 9pt"&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;
	&lt;/font&gt;
	&lt;p&gt;&lt;font COLOR="#808080" face="Courier New" style="font-size: 9pt"&gt;//&lt;/font&gt;&lt;font COLOR="#008000"&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	This method writes a record to the database for each rule that fires. This 
	record represents the data before the rule fired.&lt;br&gt;
	&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;private&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;
	&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;void&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	WriteRuleTrackingRecord(RuleActionTrackingEvent ruleActionTrackingEvent, 
	UserTrackingRecord userTrackingRecord)&lt;br&gt;
	{&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;
	string&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; PropXml = &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;string&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;.Empty&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;br&gt;
	&lt;/font&gt;&lt;font face="Courier New"&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;if&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
	(&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;this&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;._trackedProperties&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
	!= &lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;)&lt;/font&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;&lt;font style="font-size: 9pt"&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
		PropXml = CreateXmlFragment(userTrackingRecord, &amp;quot;RuleTrackingSnapshot&amp;quot;);&lt;br&gt;
		}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;&lt;font COLOR="#008000" face="Courier New" style="font-size: 9pt"&gt;//At some 
	point we might want to change this to a stored proc&lt;br&gt;
	&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;SqlCommand command =
	&lt;/font&gt;&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	SqlCommand();&lt;br&gt;
	command.Connection = &lt;/font&gt;
	&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	SqlConnection(_connectionString);&lt;br&gt;
	&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;
	command.Connection.Open();&lt;br&gt;
	SqlDataAdapter adapter = &lt;/font&gt;
	&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	SqlDataAdapter();&lt;br&gt;
	StringBuilder commandString = &lt;/font&gt;
	&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	StringBuilder();&lt;br&gt;
	&lt;br&gt;
	&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;commandString.Append 
	(&amp;quot;INSERT INTO TrackingStore..RulesTrackingData &amp;quot;);&lt;br&gt;
	commandString.Append(&amp;quot;(ComputerName, ActivityType, InstanceID, EventDateTime, 
	PolicyName, RuleName, ConditionResult, TrackingRecord)&amp;quot;);&lt;br&gt;
	commandString.Append(String.Format(&amp;quot;VALUES 
	('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}')&amp;quot;, 
	System.Environment.MachineName, 
	userTrackingRecord.ActivityType.FullName.ToString(), &lt;/font&gt;
	&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;this&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 9pt"&gt;._instanceID&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
	,System.DateTime.Now, userTrackingRecord.QualifiedName.ToString(), 
	ruleActionTrackingEvent.RuleName.ToString(), 
	ruleActionTrackingEvent.ConditionResult.ToString(), PropXml));&lt;br&gt;
	&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;br&gt;
	&lt;/font&gt;&lt;font style="font-size: 9pt" SIZE="2"&gt;&lt;font face="Courier New"&gt;
	command.CommandText = commandString.ToString();&lt;br&gt;
	command.ExecuteNonQuery();&lt;br&gt;
	command.Connection.Close();&lt;br&gt;
	}&lt;br&gt;
&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
	&lt;font SIZE="2"&gt;
	&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;private&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;
	&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;string&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
	CreateXmlFragment(UserTrackingRecord userTrackingRecord, &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
	rootNodeName)&lt;br&gt;
	&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;&lt;font face="Courier New"&gt;XmlDocument doc = &lt;/font&gt;&lt;/font&gt;
		&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
		XmlDocument();&lt;br&gt;
		&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font face="Courier New"&gt;
		XmlDocumentFragment doctype;&lt;br&gt;
		doctype = doc.CreateDocumentFragment();&lt;br&gt;
		doc.AppendChild(doctype);&lt;br&gt;
		doc.AppendChild(doc.CreateElement(rootNodeName));&lt;br&gt;
		XmlNode root = doc.DocumentElement;&lt;br&gt;
		&lt;br&gt;
		&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;
		&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;for&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;(&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
		i = 0; i &amp;lt; userTrackingRecord.Body.Count; i++)&lt;br&gt;
		&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;
		&lt;blockquote&gt;
			&lt;p&gt;&lt;font face="Courier New"&gt;XmlElement elem = 
			doc.CreateElement(userTrackingRecord.Body[i].FieldName.ToString());&lt;br&gt;
			elem.InnerText = userTrackingRecord.Body[i].Data.ToString();&lt;br&gt;
			root.AppendChild(elem);&lt;/font&gt;&lt;/p&gt;
		&lt;/blockquote&gt;
		&lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;/font&gt;
	&lt;p&gt;&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	return&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; doc.InnerXml;&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;}&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the Send method I make sure that I am only grabbing UserTrackingRecord 
objects and then I check to determine if I have a RuleActionTrackingEvent 
object.&amp;nbsp; If so then I am ready to start writing to the RulesTrackingData 
table.&amp;nbsp; In the WriteRuleTrackingRecord method I create the XML snapshot of 
the object state and then create my SQL insert statement.&amp;nbsp; Once the Send 
method is called I can start to grab data from the RuleActionTrackingEvent 
object and the UserTrackingRecord object to fill in the table with the data we 
need.&amp;nbsp; I have included the computer name as one of the fields since the 
rules run on the client side I need to make sure that I can determine where the 
rules ran.&amp;nbsp; Since this is a snapshot of code, I have left out some other 
functionality and did not take time to refactor the code for this example and 
could have consolidated it a bit.&amp;nbsp; Anyways, once this code runs and data is 
written into the RuleTrackingData table it will look like the following (I will 
let you compare the fields with the table structure above (I put a : as a field 
separator to make it easier to read)):&lt;/p&gt;
&lt;p&gt;4 : WFTEST : System.Workflow.Activities.PolicyActivity : 
4091dc04-43fe-4dde-8b80-ba837c9cc9a0 : 8/30/2006 7:03:37 AM : 
simpleDiscountPolicy : ResidentialDiscountRule : True : &amp;lt;RuleTrackingSnapshot&amp;gt;&amp;lt;orderValue&amp;gt;600&amp;lt;/orderValue&amp;gt;&amp;lt;discount&amp;gt;2&amp;lt;/discount&amp;gt;&amp;lt;/RuleTrackingSnapshot&amp;gt;&lt;br&gt;
&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you look at all of the data written to the database you should pay close 
attention to the ConditionResult field (which gets populated from
&lt;font style="font-size: 9pt" face="Courier New"&gt;&amp;nbsp;ruleActionTrackingEvent.ConditionResult)&lt;/font&gt; 
.&amp;nbsp; This will show 'true' for each rule in which the predicates match and 
the condition is executed.&amp;nbsp; This column will show 'false' for a rule where 
the predicates do not match and the else condition was executed.&amp;nbsp; For a 
rules in which the predicates do not match and there is no else condition then a 
record will not be written to the database table.&amp;nbsp; In addition, the data 
that is available to track contains the state of the object before the rules 
execute and therefore the database contains the before snapshot.&amp;nbsp; When many 
rules run it becomes quite easy to select the rules and look to see what rules 
had what affect.&amp;nbsp; The problem is that we also needed to have a snapshot of 
the object after all of the rules ran.&amp;nbsp; In the code able there is a call to 
a method that I didn't include called WriteUserTrackingRecord.&amp;nbsp; This method 
is very similar to the WriteRuleTrackingRecord method but only contains enough 
data to join to the data in the RulesTrackingData table and to contain an XML 
representation of the end state.&amp;nbsp; What makes this different is that in 
order to get this final state I needed to place a Code Activity after my Policy 
Activity.&amp;nbsp; In the Code Activity I included the following line of code:&lt;/p&gt;
&lt;font COLOR="#0000ff"&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;this&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 9pt"&gt;.TrackData(&amp;quot;WholeObject&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&amp;quot;, 
crr);&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;/p&gt;
&lt;/font&gt;
&lt;p&gt;where crr is the object that I passed into the rules engine.&lt;/p&gt;
&lt;p&gt;The TrackData takes the object and passes it as a UserTrackingRecord which 
when I receive it I call the WriteUserTrackingRecord method.&amp;nbsp; Since I am 
taking this snapshot after the policy runs I will get one of these database 
entries whereas I will get as many database entries as the number of rules that 
run in the RulesTrackingData table.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=756154" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category></item><item><title>WF Custom Activities and the ToolboxBitmap attribute</title><link>http://blogs.msdn.com/skaufman/archive/2006/08/30/732039.aspx</link><pubDate>Wed, 30 Aug 2006 19:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:732039</guid><dc:creator>skaufman</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/732039.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=732039</wfw:commentRss><description>&lt;p&gt;Ok, so this isn't just limited to Windows Workflow.&amp;nbsp; It is relevant to 
any piece of code that will end up on the Visual Studio toolbox.&lt;/p&gt;
&lt;p&gt;I am building a number of custom activities and I got tired of seeing the 
standard cog graphic in the toolbar for each one.&amp;nbsp; Within seconds all of my 
project tasks were put on hold and changing that image was placed to the top of 
my priority list.&amp;nbsp; Little did I know that it would be 1 1/2 hours later 
before I could set my gaze on all of those 16x16 pixel graphic images.&lt;/p&gt;
&lt;p&gt;Why did it take so long?&amp;nbsp; Well, it turns out that the code behind the 
ToolboxBitmap attribute code attempts to dynamically create a path to point to 
the embedded resource file.&amp;nbsp; There are times when the path created does not 
point to a valid location.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;So when I first started down this path I followed the typical route.&amp;nbsp; 
This typical path is to add a graphic as a resource of the assembly with the 
graphic marked as an embedded resource on the property page.&amp;nbsp; Then add the 
ToolboxBitmap attribute to your class providing the type of the object and the 
location for the graphic.&amp;nbsp; Compile and add your item to the toolbar and you 
should see the entry along with your graphic image.&lt;/p&gt;
&lt;p&gt;As I was researching this I found that there are two things that can mess 
this process up.&amp;nbsp; The first is to make sure that you know the fully 
qualified path of graphic, including if the graphic is in a folder in the 
solution and second is around the namespace of the assembly.&lt;/p&gt;
&lt;p&gt;If the default namespace has been changed from the original settings you will 
need to add that to the beginning of the string along with the the folder tree 
scheme.&amp;nbsp; Therefore, if I have my graphic image in a folder called Resources 
and my default namespace is BlogActivity then my resource address is 
BlogActivity.Resources.MyGraphic.png.&amp;nbsp; A problem occurs if we change the 
default namespace.&amp;nbsp; Lets say that I change it to BlogActivityTest.&amp;nbsp; 
This change would have my resource address as 
BlogActivityTest.Resources.MyGraphic.png.&amp;nbsp; This in an of itself is not a 
bad thing but in order for the ToolboxBitmap attribute to find the graphic the 
attribute code needs to find them in the context of their own namespace.&amp;nbsp; 
There are two attribute constructors that are relevant to this (there are three 
constructors but the third loads the graphic from a location on the file system 
and that is not what we want).&amp;nbsp; These two constructors are:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TooboxBitMap(typeof(&amp;lt;control&amp;gt;), &amp;quot;&amp;lt;assembly&amp;gt;.&amp;lt;resource&amp;gt;&amp;quot;)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ToolboxBitMap(typeof(&amp;lt;control&amp;gt;))&lt;/p&gt;
&lt;p&gt;The second constructor is interesting if you name the graphic the same name 
as the control.&amp;nbsp; If they are the same then the attribute code will match 
the graphic with the resource automatically.&lt;/p&gt;
&lt;p&gt;It is the first constructor that led me in circles.&amp;nbsp; As it turns out 
there is a little bug in the GetImageFromResource method.&amp;nbsp; If you have a 
namespace that is different from the assembly name (as I am sure happens in most 
scenarios) then the GetImageFromResource ends up putting the assembly name in 
front of the resource address.&amp;nbsp; In my example, my resource address would 
look something like BlogActivity.BlogActivity.Resources.MyGraphic.png and this 
location does not exist.&lt;/p&gt;
&lt;p&gt;Now that I understood what was happening I wanted to see what my Visual 
Studio project thought the address was.&amp;nbsp; Place the code below in the 
constructor of your object.&amp;nbsp;&amp;nbsp; The output of this code will show you 
the full path to your embedded resource that the runtime will use.&amp;nbsp; This 
output should match the string you are using for the second parameter.&amp;nbsp; 
This is only to loop through all of the embedded resource for debugging and is 
not meant to remain in your code.&lt;/p&gt;
&lt;font SIZE="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff" face="Courier New"&gt;public&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt; 
BlogItem()&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeComponent();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/font&gt;&lt;font SIZE="2" COLOR="#008000" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
//Remove this code after debugging&lt;/p&gt;
&lt;/font&gt;&lt;font SIZE="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
string&lt;/font&gt;&lt;font SIZE="2"&gt;[] rn = &lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;this&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt;.GetType().Assembly.GetManifestResourceNames();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
foreach&lt;/font&gt;&lt;font SIZE="2"&gt; (&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;string&lt;/font&gt;&lt;font SIZE="2"&gt; 
s &lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;in&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt; 
rn)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
System.Diagnostics.Trace.WriteLine(s);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;
&lt;p&gt;After verifying and testing this path and things still don't work then follow 
these steps.&amp;nbsp; We need to tinker with the internal dynamic path creation 
mechanism.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; First, create an internal class that is outside of the 
root namespace.&amp;nbsp; This class can be called whatever you want (in my example 
I called it EmbeddedResourceFinder)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next, use this class name in the ToolboxBitmap attribute 
instead of your control name&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lastly, change the resource location argument to match 
&amp;quot;&amp;lt;default namespace&amp;gt;.&amp;lt;resourcename&amp;gt;&amp;quot; in order to locate the resource.&lt;/p&gt;
&lt;p&gt;The code will look like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;font SIZE="2" COLOR="#0000ff"&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt; 
System.Workflow.Activities;&lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;&lt;font SIZE="2" COLOR="#008000"&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;//this internal class is needed to fool the 
ToolboxBitMap attribute so that it can actually build the&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;//assembly/namespace string correctly for it to find 
the resource.&lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;internal&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font SIZE="2"&gt;
&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;class&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt; 
EmbeddedResourceFinder&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;namespace&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt; 
BlogItem.Workflow.Activities&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ToolboxBitmap(&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff" face="Courier New"&gt;typeof&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt;(EmbeddedResourceFinder), 
&amp;quot;BlogActivity.MyGraphic.png&amp;quot;)]&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Designer(&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff" face="Courier New"&gt;typeof&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt;(PerformanceMonitorDesigner))]&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ActivityValidator(&lt;/font&gt;&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff" face="Courier New"&gt;typeof&lt;/font&gt;&lt;font SIZE="2"&gt;&lt;font face="Courier New"&gt;(PerformanceMonitorValidator))]&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;
&lt;font face="Courier New"&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;public&lt;/font&gt;&lt;font SIZE="2"&gt; 
partial &lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;class&lt;/font&gt;&lt;font SIZE="2"&gt; 
BlogActivity : SequenceActivity&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ..........&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Now that you are using the empty class and modified attribute you will find 
that the next time you add your control to the toolbox you will see your 
picture.&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=732039" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category></item><item><title>Windows Workflow Tracking and the TrackingExtract functionality</title><link>http://blogs.msdn.com/skaufman/archive/2006/08/22/Windows-Workflow-Tracking-and-the-TrackingExtract-functionality.aspx</link><pubDate>Tue, 22 Aug 2006 19:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:712840</guid><dc:creator>skaufman</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/712840.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=712840</wfw:commentRss><description>&lt;html&gt;

&lt;head&gt;
&lt;meta http-equiv="Content-Language" content="en-us"&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=windows-1252"&gt;
&lt;title&gt;New Page 1&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;I was writing a 
custom tracking service for the Windows Workflow engine for my client that will 
be used to track the rules that fired.&amp;nbsp; One of the things that I wanted to do 
was to track the values of the properties that my rules would touch.&amp;nbsp; I would 
then create an xml document which would be stored in a row in my tracking 
database.&amp;nbsp; &lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;The challenge 
was to find a way to get the internal tracking functionality to grab these 
property values.&amp;nbsp; In addition, I only wanted the properties that I was 
interested in and not every property on the class.&amp;nbsp; I found that the tracking 
infrastructure provides this functionality in the WorkFlowDataExtract class.&amp;nbsp;
&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;I did a search 
using my favorite search engine to see if there was anything documented on this 
subject.&amp;nbsp; I was surprised at the lack of information on this functionality.&amp;nbsp; 
There was one post on the WF
&lt;a href="http://forums.microsoft.com/msdn/showforum.aspx?forumid=122&amp;siteid=1"&gt;
Forums&lt;/a&gt;, which is a great resource and I highly recommend looking at these 
posts for information, but, unfortunately, it didn't expand on this class.&amp;nbsp; 
Therefore, this seemed like the perfect opportunity for a blog entry.&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in" dir="ltr"&gt;First, 
lets look at what the class does.&amp;nbsp; There are actually two classes that provide 
TrackingExtract functionality.&amp;nbsp; They are the &lt;b&gt;WorkflowDataTrackingExtract&lt;/b&gt; 
class and the &lt;b&gt;ActivityDataTrackingExtract&lt;/b&gt; class.&amp;nbsp; These classes take the 
name of a property or field that should be extracted from the root activity of 
the workflow and sent to the tracking service when a tracking point is matched.&amp;nbsp;
&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;The difference 
between these two classes is that the ActivityDataTrackingExtract class is bound 
directly to a specific activity whereas the WorkflowDataTrackingExtract can be 
assigned anywhere across the workflow.&amp;nbsp; Remember though that these classes are 
'bound' to the tracking point and can be used in either the Extracts properties 
of either the &lt;b&gt;UserTrackPoint&lt;/b&gt; or &lt;b&gt;ActivityTrackPoint&lt;/b&gt; classes.&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;The data that is 
extracted is placed in either the ActivityTrackingRecord or the 
UserTrackingRecord.&amp;nbsp; &lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;Use the Member 
method to specify the field or property to extract.&amp;nbsp; You can also associate 
additional information with the extracted data by using the Annotations 
functionality.&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;So, I wanted to 
accept a list of properties that were important to the workflow developer, in 
this case I used the List&amp;lt;string&amp;gt; generic type, which was passed in when 
instantiating the RulesTrackingService.&amp;nbsp; This list gets created in the 
program.cs file in the Main method as listed in the following code:&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;font SIZE="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;
static&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;void&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
Main()&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
WorkflowRuntime workflowRuntime = &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
WorkflowRuntime();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
string&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; connectionString = 
&amp;quot;Initial Catalog=TrackingStore;Data Source=localhost; Integrated Security=SSPI;&amp;quot;;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
List&amp;lt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;string&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&amp;gt; 
trackedProperties = &lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
List&amp;lt;&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;gt;();&lt;/font&gt;&lt;/p&gt;
&lt;font style="font-size: 9pt"&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
trackedProperties.Add(&amp;quot;orderValue&amp;quot;);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
trackedProperties.Add(&amp;quot;discount&amp;quot;);&lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
workflowRuntime.AddService(&lt;/font&gt;&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
RulesTrackingService(connectionString,trackedProperties));&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
...............&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;Once the 
RulesTrackingService gets instantiated there are two interesting pieces of code.&amp;nbsp; 
The first is the GetTrackingChannel method.&amp;nbsp; This returns a 
RuleTrackingChannel object (which inherited TrackingChannel) which is where you 
will provide the code to operate on the tracking data.&amp;nbsp; In my case, I took 
the object data and serialized it into XML so that I could place it in a row in 
the database. The second is the the GetProfile method.&amp;nbsp; Within this method, 
I have a foreach loop where I cycle through the List&amp;lt;&amp;gt; and for each entry I 
create a new WorkflowDataTrackingExtract object passing the property on the 
constructor and then add the extract object to the userTrackPoint.Extracts 
collection as shown in the code below.&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;font SIZE="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;
public&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;class&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
RulesTrackingService : TrackingService&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;{&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt" color="#808080"&gt;...........&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt" color="#808080"&gt;...........&lt;/font&gt;&lt;/p&gt;
&lt;font SIZE="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
public&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; RulesTrackingService(&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;string&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
connectionString, List&amp;lt;&lt;/font&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;gt; 
TrackedProperties)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
this&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 9pt"&gt;._connectionString&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
= connectionString;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;/p&gt;
&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
trackedProperties = TrackedProperties;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;&lt;font SIZE="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
protected&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; &lt;/font&gt;
&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;override&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt; 
TrackingChannel GetTrackingChannel(TrackingParameters parameters)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
&lt;blockquote&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	if&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; (trackedProperties != &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;)&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	return&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
	RuleTrackingChannel(parameters, &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;this&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;._connectionString&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;, 
	trackedProperties);&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;/p&gt;
	&lt;/font&gt;&lt;font SIZE="2"&gt;
	&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
	&lt;/font&gt;
	&lt;p&gt;&lt;font COLOR="#0000ff" face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	else&lt;/p&gt;
	&lt;/font&gt;
	&lt;p&gt;&lt;font face="Courier New" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
	return&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;new&lt;/font&gt;&lt;font style="font-size: 9pt"&gt; 
	RuleTrackingChannel(parameters, &lt;/font&gt;
	&lt;font COLOR="#0000ff" style="font-size: 9pt"&gt;this&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;._connectionString&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;);&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;/p&gt;
	&lt;/font&gt;&lt;font style="font-size: 9pt" SIZE="2"&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
	&lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;
	&lt;font SIZE="2"&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;/font&gt;&lt;font face="Courier New" color="#0000FF"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;
&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff"&gt;private&lt;/font&gt;
&lt;font COLOR="#0000ff"&gt;static&lt;/font&gt; TrackingProfile GetProfile()&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
TrackingProfile profile = &lt;/font&gt;&lt;font COLOR="#0000ff" face="Courier New"&gt;new&lt;/font&gt;&lt;font face="Courier New"&gt; 
TrackingProfile();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
profile.Version = &lt;/font&gt;&lt;font COLOR="#0000ff" face="Courier New"&gt;new&lt;/font&gt;&lt;font face="Courier New"&gt; 
Version(&amp;quot;1.0.0&amp;quot;);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
UserTrackPoint userTrackPoint = &lt;/font&gt;&lt;font COLOR="#0000ff" face="Courier New"&gt;
new&lt;/font&gt;&lt;font face="Courier New"&gt; UserTrackPoint();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
UserTrackingLocation userLocation = &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New"&gt;new&lt;/font&gt;&lt;font face="Courier New"&gt; 
UserTrackingLocation();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
..........&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
..........&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
userTrackPoint.MatchingLocations.Add(userLocation);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font COLOR="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
foreach&lt;/font&gt; (&lt;font COLOR="#0000ff"&gt;string&lt;/font&gt; trackedProp
&lt;font COLOR="#0000ff"&gt;in&lt;/font&gt; trackedProperties)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
WorkflowDataTrackingExtract wkflowExtract = &lt;/font&gt;
&lt;font COLOR="#0000ff" face="Courier New"&gt;new&lt;/font&gt;&lt;font face="Courier New"&gt; 
WorkflowDataTrackingExtract(trackedProp);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
userTrackPoint.Extracts.Add(wkflowExtract);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
profile.UserTrackPoints.Add(userTrackPoint);&lt;/font&gt;&lt;/p&gt;
&lt;font SIZE="2"&gt;&lt;/font&gt;
&lt;p&gt;&lt;font COLOR="#0000ff" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
return&lt;/font&gt;&lt;font face="Courier New"&gt; profile;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;The data that is 
returned from the tracking point for each of the tracked properties represents 
the data before the rule runs.&amp;nbsp; This was great for the 'before' snapshot 
but I also needed to see the 'after' snapshot.&amp;nbsp; For this functionality, I 
added a Code activity onto my workflow after the Policy activity.&amp;nbsp; In this 
activity I pass the object (in this case it is crr) that the rules operate on to 
the TrackData property which creates a UserTrackingRecord as shown in the code 
below.&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;font SIZE="2"&gt;
&lt;p&gt;&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;private&lt;/font&gt;&lt;font SIZE="2"&gt; &lt;/font&gt;
&lt;font SIZE="2" COLOR="#0000ff"&gt;void&lt;/font&gt;&lt;font SIZE="2"&gt; 
codeActivity1_ExecuteCode(&lt;/font&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;object&lt;/font&gt;&lt;font SIZE="2"&gt; 
sender, EventArgs e)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;/font&gt;
&lt;p&gt;&lt;font SIZE="2" COLOR="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;/font&gt;&lt;font SIZE="2"&gt;.TrackData(&amp;quot;WholeObject&amp;quot;, 
crr);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/font&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;Earlier I talked 
about the TrackingChannel functionality.&amp;nbsp; In this class I check to see if 
the tracking object is my custom type or if it is a base UserTrackingRecord 
(which is what the .TrackData creates).&amp;nbsp; If it is the UserTrackingRecord I 
again serialize and place this in a different table in my database.&amp;nbsp; I 
place it in a different table since there will be one of these for each policy 
whereas there will be many records for the rules tracking records.&amp;nbsp; I place 
keys on the tables so that they can be related and selected at a later time to 
actually investigate what occurred in the rules processing.&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;I now have a 
tracking service that tracks each rule that fires, including the before 
shapshot, as well an entry for the data after all of the rules have fired on the 
object.&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 10.0pt; margin: 0in"&gt;&amp;nbsp;&lt;/p&gt;

&lt;/body&gt;

&lt;/html&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=712840" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category></item><item><title>Programmatically Create Windows Workflow Rules</title><link>http://blogs.msdn.com/skaufman/archive/2006/05/15/Programmatically-Create-Windows-Workflow-Rules.aspx</link><pubDate>Mon, 15 May 2006 20:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:598165</guid><dc:creator>skaufman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/598165.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=598165</wfw:commentRss><description>&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;I am currently working with a client that is evaluating the Windows Workflow Rules Engine.&amp;nbsp; One of their requirements is that they need to be able to create the rules programmatically through their own application.&amp;nbsp; First we looked at the ability to host the Windows Workflow rules dialog boxes in our application.&amp;nbsp; We can accomplish this through the RuleSetDialog object and the RuleConditionDialog object.&amp;nbsp; Second we looked at how we could create our own UI and programmatically create the rules through an API.&amp;nbsp; Based on the requirement of the application they have decided to use their own UI.&amp;nbsp; So, the search began on how we were going to create these rules.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;The Workflow Rules Engine API works through the CodeDom system.&amp;nbsp; This makes a lot of sense since we are using code to create code - which is exactly what CodeDom was designed for. &lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;I have used a sample fictitious rule that represents the type of rule that will be created through the UI.&amp;nbsp; The rule we need to create (and the one used in the example below) is a rule that checks the model and year of a car along with the gas mileage and assigns a surcharge, if necessary.&amp;nbsp; &lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;In looking at the code below I have set up private variables to hold our data.&amp;nbsp; This could have easily been a separate object (and will be in real life).&amp;nbsp; Once I have my variables I need to setup the CodeDom objects which will reference the variables that I will be using in my rules.&amp;nbsp; &lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;The CodeDom objects that are supported in the rules object model are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeThisReferenceExpression&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeArrayIndexerExpression&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeAssignStatement &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeBinaryOperatorExpression &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeCastExpression&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeDirectionExpression &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeExpressionStatement &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeFieldReferenceExpression &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeIndexerExpression&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeMethodInvokeExpression &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeMethodReferenceExpression &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodePrimitiveExpression &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodePropertyReferenceExpression &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeTypeReference &lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;CodeTypeReferenceExpression&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;Next, I start the rule creation code.&amp;nbsp; I create a RuleSet object which I will add Rule objects to.&amp;nbsp; After I create the Rule object then I create the conditions which will be added to the rule using the Rule.Condition property(handing it a RuleExpressCondition object).&amp;nbsp; After that I will add the action using the Rule.ThenAction.Add Method (handing it a RuleStatementAction object).&amp;nbsp; I can also add the Else action using the Rule.ElseActions.Add method.&amp;nbsp; Before I can add the condition I need to create the code to represent the predicate parts that will be added to the condition.&amp;nbsp; In the code this can be seen starting with the code to create the predicate for GasMileage.&amp;nbsp; I create a CodeBinaryOperatorExpression object and then using the Left, Operator and Right properties to assembly the predicate.&amp;nbsp; I continue this for each of the predicates I will need for this rule (in this case there are 3).&amp;nbsp; I have shown in the code how to compare against an integer (with the GasMileage predicate), against a string (with the ModelYear predicate) as well as against an Enum type (with the CarCategory predicate).&amp;nbsp; These predicates also show how to use the CodeBinaryOperatorType object with both the .ValueEquality and .LessThan operators.&amp;nbsp; An interesting find is that there is no inequality operator.&amp;nbsp; To find inequality you need to create the syntax as (CarCategory == "Sports") == false.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;Once I have created the predicates that represent each of the parts of my rule I then need to join the predicates and create the condition which will be passed to a RuleExpressionCondition object.&amp;nbsp; As seen in the code below I take the first two predicates; the ruleGasMileageTest object and using a BooleanAnd operator join to the ruleCarCategoryTest object.&amp;nbsp; If I only had two predicates I would be done and could add the condition object to the rule (carChargeRule).&amp;nbsp; Since I had three predicates I need to take the condition object created from the joining of the first two predicates and join them to the third predicate (ruleModelYearTest) to create the final condition (ruleCondition2) which will be added to the rule.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;At this point we have the 'if' portion of the rule complete.&amp;nbsp; We now need to create the 'then' portion.&amp;nbsp; This is accomplished using the Rule.ThenAction.Add method as seen at the bottom of the code.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;After you have looked at the code make sure to look at the image of the locals window which follows the code.&amp;nbsp; This screen shot shows the rules code that all of this CodeDom code created.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; ......&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;{&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;//Object Items&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; CarName = &lt;SPAN style="COLOR: maroon"&gt;"Jaguar"&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; CarModel = &lt;SPAN style="COLOR: maroon"&gt;"XK SLE"&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; ModelYear = &lt;SPAN style="COLOR: maroon"&gt;"2009"&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CarCategory&lt;/SPAN&gt; carCategory = &lt;SPAN style="COLOR: teal"&gt;CarCategory&lt;/SPAN&gt;.SportsCar;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; GasMileage = 12;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; SurchargeRate = 0;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; BuildRuleSet()&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;{&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;RuleSet&lt;/SPAN&gt; surchargeRuleSet = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;RuleSet&lt;/SPAN&gt;(&lt;SPAN style="COLOR: maroon"&gt;"SurchargeRuleSet"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// Define property and activity reference expressions through CodeDom functionality&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeThisReferenceExpression&lt;/SPAN&gt; thisRef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeThisReferenceExpression&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt; CarNameRef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt;(thisRef, &lt;SPAN style="COLOR: maroon"&gt;"CarName"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt; CarCategoryRef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt;(thisRef, &lt;SPAN style="COLOR: maroon"&gt;"carCategory"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeTypeReferenceExpression&lt;/SPAN&gt; CategoryEnumRef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeTypeReferenceExpression&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: teal"&gt;CarCategory&lt;/SPAN&gt;));&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt; ModelYearRef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt;(thisRef, &lt;SPAN style="COLOR: maroon"&gt;"ModelYear"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt; SurchargeRef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt;(thisRef, &lt;SPAN style="COLOR: maroon"&gt;"SurchargeRate"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt; GasMileageRef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt;(thisRef, &lt;SPAN style="COLOR: maroon"&gt;"GasMileage"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// IF GasMileage &amp;lt; 15 AND CarCategory = Sports AND ModelYear = 2009&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// THEN Surcharge = $500&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;Rule&lt;/SPAN&gt; carChargeRule = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Rule&lt;/SPAN&gt;(&lt;SPAN style="COLOR: maroon"&gt;"CarChargeRule"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;surchargeRuleSet.Rules.Add(carChargeRule);&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// define first predicate: GasMileage &amp;lt; 15&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt; ruleGasMileageTest = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleGasMileageTest.Left = GasMileageRef;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleGasMileageTest.Operator = &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorType&lt;/SPAN&gt;.LessThan;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleGasMileageTest.Right = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodePrimitiveExpression&lt;/SPAN&gt;(15); &lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// define second predicate: CarCategory = Sports&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt; ruleCarCategoryTest = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCarCategoryTest.Left = CarCategoryRef;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCarCategoryTest.Operator = &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorType&lt;/SPAN&gt;.ValueEquality;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCarCategoryTest.Right = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeFieldReferenceExpression&lt;/SPAN&gt;(CategoryEnumRef, &lt;SPAN style="COLOR: maroon"&gt;"SportsCar"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// define third predicate: ModelYear = 2009&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt; ruleModelYearTest = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleModelYearTest.Left = ModelYearRef;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleModelYearTest.Operator = &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorType&lt;/SPAN&gt;.ValueEquality;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleModelYearTest.Right = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodePrimitiveExpression&lt;/SPAN&gt;(&lt;SPAN style="COLOR: maroon"&gt;"2009"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// join the first two predicates into a single condition&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt; ruleCondition = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCondition.Left = ruleGasMileageTest;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCondition.Operator = &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorType&lt;/SPAN&gt;.BooleanAnd;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCondition.Right = ruleCarCategoryTest;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// join the third predicate into the condition&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt; ruleCondition2 = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorExpression&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCondition2.Left = ruleCondition;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCondition2.Operator = &lt;SPAN style="COLOR: teal"&gt;CodeBinaryOperatorType&lt;/SPAN&gt;.BooleanAnd;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleCondition2.Right = ruleModelYearTest;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;carChargeRule.Condition = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;RuleExpressionCondition&lt;/SPAN&gt;(ruleCondition2);&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// add the action: Surcharge = 500&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;CodeAssignStatement&lt;/SPAN&gt; ruleSurchargeAction = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodeAssignStatement&lt;/SPAN&gt;(SurchargeRef, &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CodePrimitiveExpression&lt;/SPAN&gt;(500));&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;carChargeRule.ThenActions.Add(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;RuleStatementAction&lt;/SPAN&gt;(ruleSurchargeAction));&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// Add the ruleset&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: teal"&gt;RuleDefinitions&lt;/SPAN&gt; ruleDef = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;RuleDefinitions&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;ruleDef.RuleSets.Add(surchargeRuleSet);&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; COLOR: green; FONT-FAMILY: Courier New"&gt;// Set the RuleDefinitions on the workflow&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.SetValue(&lt;SPAN style="COLOR: teal"&gt;RuleDefinitions&lt;/SPAN&gt;.RuleDefinitionsProperty, ruleDef);&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;}&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;enum&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;CarCategory&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;{&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;SportsCar = 0,&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;Sedan = 1,&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;SUV = 2,&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;.......&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;}&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 9pt; MARGIN: 0in; FONT-FAMILY: Courier New"&gt;&lt;A href="http://home.comcast.net/~stephen.kaufman/LocalsWindow.jpg"&gt;&lt;IMG height=325 src="http://home.comcast.net/~stephen.kaufman/LocalsWindow.jpg" width=1022 border=0&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=598165" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category></item><item><title>BizTalk and Windows Workflow</title><link>http://blogs.msdn.com/skaufman/archive/2005/11/22/495860.aspx</link><pubDate>Tue, 22 Nov 2005 21:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:495860</guid><dc:creator>skaufman</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/skaufman/comments/495860.aspx</comments><wfw:commentRss>http://blogs.msdn.com/skaufman/commentrss.aspx?PostID=495860</wfw:commentRss><description>&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;It always comes down to choices.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The biggest part of choosing is knowing what you gain and what you give up with each alternative.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Whenever I start talking about Windows Workflow I am always asked many questions.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Typically the first question that is asked is "does this mean that BizTalk is going away?" followed by "well, then when do I use each one".&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;That is what I want to discuss in this blog entry.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;First, BizTalk is not going away.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;I want to put a definition around BizTalk to make it easier to compare to Windows Workflow.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;BizTalk Server is an enterprise level workflow and message processing environment.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This environment is tried and tested (extremely rigorously over the last many years).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;BizTalk also includes many adapters to connect to a variety of back end system.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Out of the box, BizTalk provides scalability, manageability, tracking, logging &amp;amp; administration tools.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;Windows Workflow is an SDK for creating workflow based applications.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The tools are there to&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;build a host and to render a graphical workflow environment.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Scalability is possible with Windows Workflow but it is up to the developer to create a truly scalable solution.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In addition, there are administrative functions through runtime and tracking visibility but there is not an out of the box administration tool as this is also up to the host developer to create.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;The message that I tell people is to use BizTalk when you want to target users/clients that want to span multiple applications whereas Windows Workflow would be used when you want to target users/clients that want workflow within an application.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;Now after saying that I know the next question you would ask and it is "Are you saying that Windows Workflow doesn't scale?".&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The answer is certainly yes, Windows Workflow scales.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Windows Workflow scales based on your implementation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This is similar to what you would expect when scaling any application built using the .NET framework.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Windows Workflow does not come pre-built as a server application ready to scale as does BizTalk but if you develop the appropriate host and put in place the appropriate development effort then it will certainly scale.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;It has been stated that in the future Windows Workflow will be the core workflow engine in all of the Microsoft products that offer workflow.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This means that future versions of BizTalk will be built on top of and extend Windows Workflow.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This also means that products like SharePoint will also offer workflow based on top of Windows Workflow.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana; mso-outline-level: 1"&gt;So, to summarize, Windows Workflow is great for workflow within an application whereas BizTalk is great for workflow across applications and this is precisely why BizTalk shines in Enterprise Application Integration scenarios.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=495860" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/skaufman/archive/tags/BizTalk/default.aspx">BizTalk</category><category domain="http://blogs.msdn.com/skaufman/archive/tags/WF/default.aspx">WF</category></item></channel></rss>