Tracking an Expression activity in Windows Workflow Foundation

Since the nodes in a Flowchart do not derive from Activity, they do not have the tracking capabilities of activities. However, because Expressions are activities, it is possible to track the Condition property of a FlowDecision activity.

The following code demonstrates how to create an Expression that can then participate in tracking.

 

 public class TrackResult<T> : CodeActivity<T>
 {
 public InArgument<T> Expression { get; set; }
 
 protected override T Execute(CodeActivityContext context)
 {
 T result = context.Get(Expression);
 // Either explicitly call context.Track here, or just set up a tracking profile on TrackResult.Expression
 return result;
 }
 }
 

Note that in order to use a custom activity for the Condition property of a FlowDecision activity, the workflow must be created in code rather than using the designer. The following code snippet (from the Flowchart with Fault Handling sample) demonstrates how to create a flowchart in code.

 private static Activity CreateFlowchartWithFaults(string promoCode, int numKids)
 {
 Variable<string> promo = new Variable<string> { Default = promoCode };
 Variable<int> numberOfKids = new Variable<int> { Default = numKids };
 Variable<double> discount = new Variable<double>();
 DelegateInArgument<DivideByZeroException> ex = new DelegateInArgument<DivideByZeroException>();
 
 FlowStep discountNotApplied = new FlowStep
 {
 Action = new WriteLine 
 { 
 DisplayName = "WriteLine: Discount not applied", 
 Text = "Discount not applied" 
 },
 Next = null
 };
 
 FlowStep discountApplied = new FlowStep
 {
 Action = new WriteLine 
 {
 DisplayName = "WriteLine: Discount applied",
 Text = "Discount applied " 
 },
 Next = null
 };
 
 FlowDecision flowDecision = new FlowDecision 
 {
 Condition = ExpressionServices.Convert<bool>((ctx) => discount.Get(ctx) > 0),
 True = discountApplied,
 False = discountNotApplied
 };
 
 FlowStep singleStep = new FlowStep
 {
 Action = new Assign
 {
 DisplayName = "discount = 10.0",
 To = new OutArgument<double> (discount),
 Value = new InArgument<double> (10.0)
 },
 Next = flowDecision
 };
 
 FlowStep mnkStep = new FlowStep
 {
 Action = new Assign
 {
 DisplayName = "discount = 15.0",
 To = new OutArgument<double> (discount),
 Value = new InArgument<double> (15.0)
 },
 Next = flowDecision
 };
 
 FlowStep mwkStep = new FlowStep
 {
 Action = new TryCatch
 {
 DisplayName = "Try/Catch for Divide By Zero Exception",
 Try = new Assign
 {
 DisplayName = "discount = 15 + (1 - 1/numberOfKids)*10",
 To = new OutArgument<double>(discount),
 Value = new InArgument<double>((ctx) => (15 + (1 - 1 / numberOfKids.Get(ctx)) * 10))
 },
 Catches = 
 {
 new Catch<System.DivideByZeroException>
 {
 Action = new ActivityAction<System.DivideByZeroException>
 {
 Argument = ex,
 DisplayName = "ActivityAction - DivideByZeroException",
 Handler =
 new Sequence
 {
 DisplayName = "Divide by Zero Exception Workflow",
 Activities =
 {
 new WriteLine() 
 { 
 DisplayName = "WriteLine: DivideByZeroException",
 Text = "DivideByZeroException: Promo code is MWK - but number of kids = 0" 
 },
 new Assign<double>
 {
 DisplayName = "Exception - discount = 0", 
 To = discount,
 Value = new InArgument<double>(0)
 }
 }
 }
 }
 }
 }
 },
 Next = flowDecision
 };
 
 FlowStep discountDefault = new FlowStep
 {
 Action = new Assign<double>
 {
 DisplayName = "Default discount assignment: discount = 0",
 To = discount,
 Value = new InArgument<double>(0)
 },
 Next = flowDecision
 };
 
 FlowSwitch<string> promoCodeSwitch = new FlowSwitch<string>
 {
 Expression = promo,
 Cases =
 {
 { "Single", singleStep },
 { "MNK", mnkStep },
 { "MWK", mwkStep }
 },
 Default = discountDefault
 };
 
 Flowchart flowChart = new Flowchart
 {
 DisplayName = "Promotional Discount Calculation",
 Variables = {discount, promo, numberOfKids},
 StartNode = promoCodeSwitch,
 Nodes = 
 { 
 promoCodeSwitch, 
 singleStep, 
 mnkStep, 
 mwkStep, 
 discountDefault, 
 flowDecision, 
 discountApplied, 
 discountNotApplied
 }
 };
 return flowChart;
 }