How can I create WF rules in code?
I am creating an ActivityToolboxItem for a custom Activity in WF. I am trying to do as much design work as possible in the CreateComponentsCore method. What I am trying to do is the following:
1) My custom activity ( TriggerActivity , sequence) containing the following:
2) A TriggerEvaluatorActivity (simple activity) that is bound to a property on TriggerActivity 3) IfElseActivity , which has two branches
4) IfElseBranchActivity , which contains 5) A TerminateActivity and
6) IfElseBranchActivity , which is empty, through which the thread is executed when TriggerEvaluatorActivity evaluates to true.
Designers disable TriggerEvaluatorActivity with one or more implementations that perform complex evaluations in the execution context.
It's pretty easy to set up in code, but I'm totally stuck on how to deploy the ActivityCondition , which will be added to the IfElseBranchActivity to control the flow of execution.
All I need to do is evaluate the property on the TriggerEvaluatorActivity . I have created a lovely fine rule through the dom code, but I cannot set it directly on IfElseBranchActivity, I have to cross out the rule somewhere and point it in the action.
So I guess my question is once I have created a rule in code, how do I add a rule to a workflow from a custom ActivityToolboxItem so that the activities I create in code can reference it?
a source to share
According to this question on MSDN , it is stored in a dependency property in the root activity. Not sure if the example code is correct or not yet.
Working. Here's some sample code:
protected override System.ComponentModel.IComponent[]
CreateComponentsCore(System.ComponentModel.Design.IDesignerHost host)
{
var trigger = new Trigger() { Name = "Trigger" };
var never = new Never() { Name = "NeverTrigger" };
var ifelse = new IfElseActivity() { Name = "IfElse" };
var stop = new TerminateActivity() { Name = "StopJob" };
var failed = new IfElseBranchActivity() { Name = "NotTriggered" };
var succeeded = new IfElseBranchActivity() { Name = "Triggered" };
// build tree
failed.Activities.Add(stop);
ifelse.Activities.Add(failed);
ifelse.Activities.Add(succeeded);
trigger.Activities.Add(never);
trigger.Activities.Add(ifelse);
// create rule if it doesn't already exist
var ruleDefinitions = GetRuleDefinitions
(host.RootComponent as DependencyObject);
if (!ruleDefinitions.Conditions.Contains(RuleName))
{
var neverTrigger =
new CodePropertyReferenceExpression
(new CodeThisReferenceExpression(),
"NeverTrigger");
var triggered =
new CodePropertyReferenceExpression
(neverTrigger,
"Triggered");
var falseSide = new CodeBinaryOperatorExpression();
falseSide.Left = triggered;
falseSide.Right = new CodePrimitiveExpression(false);
falseSide.Operator = CodeBinaryOperatorType.ValueEquality;
var ruleCondition = new RuleExpressionCondition
(RuleName, falseSide);
ruleDefinitions.Conditions.Add(ruleCondition);
}
// add rule to the failed branch;
// don't need a rule for the succeeded branch
failed.Condition = new RuleConditionReference()
{ ConditionName = RuleName };
return new IComponent[] { trigger };
}
private RuleDefinitions GetRuleDefinitions
(DependencyObject rootComponent)
{
var ruleDefinitions = rootComponent.GetValue
(RuleDefinitions.RuleDefinitionsProperty) as RuleDefinitions;
if (ruleDefinitions == null)
{
ruleDefinitions = new RuleDefinitions();
rootComponent.SetValue(RuleDefinitions.RuleDefinitionsProperty,
ruleDefinitions);
}
return ruleDefinitions;
}
a source to share