How to: Use Rule Conditions in Workflows

Conditions are used to drive the execution behavior of activities—for example, determining whether a given IfElseBranchActivity will execute. You can specify conditions as a CodeCondition, which will have a configured handler in the code beside, as shown in the topic How to: Use Conditions Through Code. Or, you can specify conditions as a RuleConditionReference. A RuleConditionReference will point to a RuleCondition definition in a .rules file that is associated with the workflow in the workflow project. You can use rule conditions instead of code conditions in any activities that support conditions.

The primary reason for a developer to use a rule condition instead of a code condition is that rule conditions become part of the model and can be dynamically updated at run time on executing workflow instances. A secondary advantage of rule conditions is that as part of the model, more sophisticated tools can be built on top of the model to provide additional authoring experiences, dependency management, cross-condition analysis, and so on.

Assigning Rules to Activity Conditions

To use rules for activity conditions, create a file that has the .rules extension. This file must be compiled into your assembly as an embedded resource. The following example shows a .rules file that contains a single rule condition named CustomerHasCouponsCondition. The rule will evaluate to true if the corresponding workflow property named CustomHasCoupons returns true.

<RuleDefinitions xmlns="https://schemas.microsoft.com/winfx/2006/xaml/workflow">
  <RuleDefinitions.Conditions>
    <RuleExpressionCondition Name="CustomerHasCouponsCondition">
      <RuleExpressionCondition.Expression>
        <ns0:CodeBinaryOperatorExpression Operator="ValueEquality" xmlns:ns0="clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
          <ns0:CodeBinaryOperatorExpression.Left>
            <ns0:CodePropertyReferenceExpression PropertyName="CustomerHasCoupons">
              <ns0:CodePropertyReferenceExpression.TargetObject>
                <ns0:CodeThisReferenceExpression />
              </ns0:CodePropertyReferenceExpression.TargetObject>
            </ns0:CodePropertyReferenceExpression>
          </ns0:CodeBinaryOperatorExpression.Left>
          <ns0:CodeBinaryOperatorExpression.Right>
            <ns0:CodePrimitiveExpression>
              <ns0:CodePrimitiveExpression.Value>
                <ns1:Boolean xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">true</ns1:Boolean>
              </ns0:CodePrimitiveExpression.Value>
            </ns0:CodePrimitiveExpression>
          </ns0:CodeBinaryOperatorExpression.Right>
        </ns0:CodeBinaryOperatorExpression>
      </RuleExpressionCondition.Expression>
    </RuleExpressionCondition>
  </RuleDefinitions.Conditions>
</RuleDefinitions>

Note

The name of the .rules file must be the same as the class name of the workflow. If it is not, the workflow will compile successfully but when it is invoked a validation exception will be thrown and the workflow will fail to start. When developing a workflow in Visual Studio 2008 a workflow’s class name can be changed by right-clicking the workflow in Solution Explorer and choosing Rename. This changes the class name of the workflow, and also changes the names of the supporting files including the .rules file.

To use a rule condition on an activity, create a new RuleConditionReference. Set the ConditionName property equal to the value of the Name attribute of the RuleExpressionCondition element in the .rules file. In the example shown earlier, the Name of the rule is CustomerHasCouponsCondition. To associate the RuleConditionReference with a condition on an activity, set the Condition property equal to the RuleConditionReference you created.

The following workflow definition shows how to use rule conditions with an IfElseActivity. The .rules file that was created earlier uses the value of the CustomerHasCoupons property in the workflow to evaluate the condition. In the InitializeComponent method, a RuleConditionReference is created and assigned to the Condition property of the IfElseActivity.

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace CustomerCouponApplication
{
    public sealed partial class CouponsWorkflow: SequentialWorkflowActivity
    {
        private bool customerHasCoupons = false;

        private IfElseBranchActivity elseHasCoupons;
        private IfElseBranchActivity ifHasCoupons;
        private IfElseActivity checkForCouponsActivity;

        public bool CustomerHasCoupons
        {
            get { return customerHasCoupons; }
            set { customerHasCoupons = value; }
        }

        public CouponsWorkflow()
        {
            InitializeComponent();
        }

        [System.Diagnostics.DebuggerNonUserCode]
        private void InitializeComponent()
        {
            this.CanModifyActivities = true;
            
            System.Workflow.Activities.Rules.RuleConditionReference hasCouponsCondition = new System.Workflow.Activities.Rules.RuleConditionReference();
            this.elseHasCoupons = new System.Workflow.Activities.IfElseBranchActivity();
            this.ifHasCoupons = new System.Workflow.Activities.IfElseBranchActivity();
            this.checkForCouponsActivity = new System.Workflow.Activities.IfElseActivity();

            // 
            // ifHasCoupons
            // 
            hasCouponsCondition.ConditionName = "CustomerHasCouponsCondition";
            this.ifHasCoupons.Condition = hasCouponsCondition;
            this.ifHasCoupons.Name = "ifElseBranchActivity1";
            // 
            // elseHasCoupons
            // 
            this.elseHasCoupons.Name = "ifElseBranchActivity2";
            // 
            // checkForCouponsActivity
            // 
            this.checkForCouponsActivity.Activities.Add(this.ifHasCoupons);
            this.checkForCouponsActivity.Activities.Add(this.elseHasCoupons);
            this.checkForCouponsActivity.Name = "ifCustomerHasCouponsActivity";
            // 
            // Workflow1
            // 
            this.Activities.Add(this.checkForCouponsActivity);
            this.Name = "CouponsWorkflow";
            this.CanModifyActivities = false;
        }
    }
}

See Also

Reference

RuleConditionReference
RuleCondition
CodeCondition
ConditionName

Concepts

How to: Use Conditions Through Code
Workflow Changes to Rule Conditions
CodeDom Types Supported by Windows Workflow Foundation
Using RuleSets in Workflows
Using the IfElseActivity Activity
Using the WhileActivity Activity
Using the ReplicatorActivity Activity
Using the ConditionedActivityGroup Activity

Other Resources

Tutorial: Use Rules and Conditions in WF