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;
}