wca.exe - Workflow Communication Activities Generation
I have already written about External Data Exchange mechanism in Windows Workflow Foundation earlier. I mentioned that using CallExternalMethod and HandleExternalEvent activities is the way to communicate with the hosting environment.
Using these activities, you have to define which External Data Exchange Interface to use, the method to call (or the event to register for) and the arguments. Isn't there a way to create a "Strongly typed" communication activities for a specific Data Exchange Interface?
Well, it turns out there is…
WCA (short name for Workflow Communication Activities) is a tool that when given an assembly which contains External Data Exchange Interface(s), creates custom activities for calling the interface methods and handling the interface events.
Using wca.exe
If you have a Data Exchange interface in a project (it can be either .dll or .exe) that looks somewhat similar to this:
[ExternalDataExchange]
public interface IDocumentApproval
{
// Send document for approval
void RequestDocumentApproval(Guid documentId, String approver);
void ApproveDocument(Guid documentId, String approver);
// Received document for approval
event EventHandler<DocumentEventArgs> DocumentApproved;
}
You can use wca.exe (located in C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin) with the assembly name as parameter to generate the communication activities. For example:
wca.exe DocumentApproval.dll
The wca.exe will have the following output:
Processing interface 'Bursteg.Samples.WF.wca.IDocumentApproval'
Generating InvokeMethod for 'RequestDocumentApproval'
Generating InvokeMethod for 'ApproveDocument'
Wrote file: IDocumentApproval.Invokes.cs
Generating EventSink for 'DocumentApproved'
Wrote file: IDocumentApproval.Sinks.cs
Done processing. Exiting.
Examining the output of the tool, you can see that 2 files were created: IDocumentApproval.Invokes.cs that contains 2 Activities that Inherit from CallExternalMethod activity, and IDocumentApproval.Sinks.cs that contains a single activity that inherits from HandleExternalEvent activity. The generated activities match the definition of the original External Data Exchange Interface.
Using wca.exe from Visual Studio
wca.exe is a very useful tool, but will be more convenient to use if it is available within the development environment.
In order to add it as a tool, follow these steps:
1. from Tools menu, select External Tools.
2. In the External Tools Dialog, add a new tool and set the following properties:
Title: WCA (You can change this one…)
Command: C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\wca.exe
Arguments: $(TargetName)$(TargetExt) /o:$(ProjectDir) /c
Initial Directory: $(TargetDir)

Using the above settings will generate the output files in the project's directory using the .dll in the target directory (bin\debug).
From now on, you can select any project that contains a External Data Exchange Interface definition, and from the Tools menu select to execute WCA tool. After generating the communication activities, use the "Show All Files" button in the solution explorer to view the new files, and to include them in your project.
Enjoy!
Workflow Persistence Point with PersistActivity | PersistOnClose
The WF runtime persists workflow instances to the persistence store when the execution of an activity with System.Workflow.ComponentModel.PersistOnCloseAttribute on it is completed. One good out-of-the-box example is the TransactionScopeActivity: When it's execution is completed, the Workflow Runtime persists the Workflow instance using the Persistence Service.
If you have a point in your business process where you want to persist the instance of the workflow, and this point is not right after a TransactionScopeActivity has been completed, you can use an activity that will tell the runtime that now is the time to persist. Actually, the activity does nothing, and it is only decorated with PersistOnClose Attribute.
Such an activity will look like:
[PersistOnClose]
public partial class PersistActivity : Activity {
public PersistActivity()
{
InitializeComponent();
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
return ActivityExecutionStatus.Closed;
}
}
And you've just created a Workflow Persistence Point with PersistActivity.
Enjoy!
Enterprise Library 3.0 first CTP (December 2006 CTP) is available at http://www.codeplex.com/entlib.
This CTP includes a partial implementation of the Validation Application Block, Application Block Software Factory, Visual Studio-integrated config tool, DAAB enhancements and more.
You can download the CTP from here. You'll also find the release notes for this CTP in this page.
Enjoy!
As of today, you can register and receive updates from my blog using Windows Live Alerts. Just click the Windows Live Alerts icon by my picture, and you're updated.

If you want to setup alerts for your blog, just follow the instructions shown at this page.
Enjoy!
Microsoft Israel is having the biggest event ever been in Israel for developers this January. I am very excited towards this event both about the technologies that will be discussed there, but mostly because I am one of the people who is going to talk about them!
I'll be giving a talk about Windows Workflow Foundation which I have been playing with for the last 6 month! The session is called "Technology In Action! Windows Workflow Foundation Advanced Techniques", and requires some background in WF, since we will go deep into some advanced and very interesting scenarios using WF showing large amount of coding. If you are into watching what WF can do, you should not miss this session. You will go out with great insight about the power that this technology can add to your applications.

See you there!
"One of the coolest new capabilities in Enterprise Library v3 is the Application Block Software Factory. As its name ever-so-subtly suggests, this will be a software factory for building your own application blocks. We'll be including an early drop of this factory in the first preview release of Enterprise Library v3..."
Check out Tom's blog for more details...

Enjoy!
PDC07 Finally announced! I know I want to be there... How about you?
A short reminder about rules and conditions
Condition - Expression that evaluates to True or False
Rule – Modeled as:
If <Condition>
Then <RuleAction(s)>
Else <RuleAction(s)>
RuleSet - Collection of Rules with a set of execution semantics.
The RuleSet Editor that ships with Windows Workflow Foundation may be very convenient for developers, but for the end-user or even the business analyst it might not.
Building another user interface for editing rules, developers use CodeDom in order to create their rules conditions and actions on-the-fly.

Both conditions and actions are just code expressions or statements expressed with CodeDom. In order to use them in the context of rules, they must be wrapped with designated wrappers.
Assuming that my custom object (which the rules will be executed on) look like:
public class Technology
{
public Technology(string tech)
{
this.technology = tech;
this.rocks = false;
}
private string technology;
private bool rocks;
public string TechnologyName
{
get { return technology; }
set { technology = value; }
}
public bool Rocks
{
get { return rocks; }
set { rocks = value; }
}
}
Now, I want to create a rule that checks if the technology name is “WF”, and sets rocks property if it is. Describing it with (pseudo) code, the rule looks like:
if (this.Technology == "WF")
this.Rocks = true;
else
this.Rocks = false;
Let’s separate the code required to build this rule into several parts:
Building the Condition
// this.
CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();
// .Technology
CodePropertyReferenceExpression technologyRef = new CodePropertyReferenceExpression(thisRef, "TechnologyName");
// "WF"
CodePrimitiveExpression wfConstant = new CodePrimitiveExpression("WF");
// if ( this.Technology == "WF" )
CodeBinaryOperatorExpression cond = new CodeBinaryOperatorExpression();
cond.Left = technologyRef;
cond.Operator = CodeBinaryOperatorType.ValueEquality;
cond.Right = wfConstant;
Building the ThanAction and ElseAction
// .Technology
CodePropertyReferenceExpression rocksRef = new CodePropertyReferenceExpression(thisRef, "Rocks");
// true
CodePrimitiveExpression trueExpression = new CodePrimitiveExpression(true);
// false
CodePrimitiveExpression falseExpression = new CodePrimitiveExpression(false);
// this.Rocks = true;
CodeAssignStatement assignTrue = new CodeAssignStatement();
assignTrue.Left = rocksRef;
assignTrue.Right = trueExpression;
// this.Rocks = true;
CodeAssignStatement assignFalse = new CodeAssignStatement();
assignFalse.Left = rocksRef;
assignFalse.Right = falseExpression;
Wrapping with Workflow Rules objects
// Wrap it all togother
Rule rule = new Rule("rule1");
rule.Condition = new RuleExpressionCondition(cond);
rule.ThenActions.Add(new RuleStatementAction(assignTrue));
rule.ElseActions.Add(new RuleStatementAction(assignFalse));
// Create a RuleSet
RuleSet rs = new RuleSet();
rs.ChainingBehavior = RuleChainingBehavior.None;
rs.Rules.Add(rule);
Executing the RuleSet over an instance of Technology class
Technology t1 = new Technology("WF");
// Validate RuleSet
RuleValidation validation = new RuleValidation(typeof(Technology), null);
rs.Validate(validation);
ValidationErrorCollection errors = validation.Errors;
if (errors.Count > 0)
{
// TODO: Check if there are any errors and handle
}
// Execute
RuleExecution execution = new RuleExecution(validation, t1);
rs.Execute(execution);
Console.WriteLine("{0} {1}!", t1.TechnologyName, (t1.Rocks ? "Rocks" : "does not rock at all!"));
What is the expected result?
Enjoy!