Skip to Content
Evaluate Get Started

Transition

A transition connects two activities in a scheme. Every transition has a source activity where the transition starts, and a target activity where the process instance moves after the transition fires.

What causes a transition to fire depends on its trigger. A command trigger fires when someone calls a named command. An auto trigger fires after the process instance enters the source activity and its implementation completes. A timer trigger fires when a configured timer expires.

A transition can also have conditions that select a route based on process data, and restrictions that control actor access to a command transition. A condition answers whether the route can run now; a restriction answers whether the actor may run it. When a transition fires, the process instance moves to the target activity and that activity's actions run.

Transition properties

Each transition has a set of properties that define its source, target, trigger, and behavior.

Core properties

These are the most commonly configured properties:

Core transition properties
PropertyTypeDescription
NamestringUnique identifier for the transition within the scheme
FromActivityDefinitionSource activity where the process instance must be for this transition to fire
ToActivityDefinitionTarget activity where the process instance moves when the transition fires
Classifierenum (NotSpecified, Direct, Reverse)Classifies the transition direction. Direct for forward transitions, Reverse for backward or corrective, NotSpecified when not classified
Triggertrigger (Command, Auto, Timer)What causes the transition to fire. Command fires for a matching command, Auto after the source implementation, and Timer on expiry
Conditionslist of conditionsDetermines whether the transition is eligible to fire. Multiple action or expression conditions are combined by ConditionsConcatenationType
Restrictionslist of restrictionsAllow and restrict actor rules that control access to a command transition

Scenario-specific properties

These properties are needed in specific cases such as combining rules, subprocess integration, or metadata:

Scenario-specific transition properties
PropertyTypeDescription
ConditionsConcatenationTypeenum (And, Or)How multiple conditions are combined. And means all must pass, Or means any one is enough
AllowConcatenationTypeenum (And, Or)How multiple allow restrictions are combined
RestrictConcatenationTypeenum (And, Or)How multiple restrict restrictions are combined
UserCommentstringOptional custom comment attached to the transition
Annotationslist of AnnotationKey-value metadata attached to the transition; see Annotations
IsForkboolMarks this transition as the start or end of a subprocess branch
SubprocessInOutDefinitionenum (Auto, Start, Finalize)Defines how the transition relates to a subprocess
MergeViaSetStateboolSubprocess only. On a finalizing transition, selects a forced parent state change instead of evaluating auto transitions from the target activity
DisableParentStateControlboolSubprocess only. On a starting transition, disables automatic subprocess deletion based on the parent activity

Transition and subprocess

A transition can start a subprocess or merge it back into the parent. To make a transition do either, add IsFork="true" to the transition and set SubprocessInOutDefinition:

  • SubprocessInOutDefinition="Start" - this transition creates a new subprocess when it fires.
  • SubprocessInOutDefinition="Finalize" - this transition merges the subprocess back when it fires.
  • SubprocessInOutDefinition="Auto" - the runtime decides based on where the transition sits in the scheme.

MergeViaSetState applies to a transition that finalizes a subprocess. With false, the runtime merges the parameters, deletes the subprocess, and evaluates auto transitions that leave the finalizing transition's target activity. If none fires, the parent remains in its current activity and becomes idle. With true, the runtime instead forcibly moves the parent to the target activity and runs that activity's implementation.

DisableParentStateControl applies to a transition that starts a subprocess. With false, the runtime calculates the parent activities where the subprocess may exist and deletes it when the parent leaves that set. With true, parent activity changes do not delete the subprocess automatically; its own completion or merge behavior still applies.

For a full explanation with examples, see the Subprocess concept page.

What is Classifier

The Classifier property classifies the direction of a transition. It has three possible values:

  • NotSpecified. No classification assigned. This is the default value.
  • Direct. A forward transition in the normal workflow flow.
  • Reverse. A backward or corrective transition used to return the process instance to an earlier activity.

The classifier does not select or trigger a transition; triggers and conditions do. The runtime uses the classifier to limit pre-execution to direct transitions, filter direct and reverse actor queries, and record the transition direction.

What is Trigger

The Trigger property defines what causes the transition to fire.

  • Command. Fires when someone executes a matching command. The command must be declared separately in the scheme's <Commands> section.
  • Auto. Fires automatically after the process instance enters the source activity and its implementation completes. No external call is needed. Useful for routing logic that should run immediately.
  • Timer. Fires when a configured timer expires. Timer transitions do not need a command call.

How transitions connect activities in a scheme

Transitions are declared in the <Transitions> section of a scheme. Each <Transition> element specifies the source and target activities, the classifier, and nested elements for triggers, conditions, and restrictions. Activities are declared in the <Activities> section and referenced by name in the transitions.

Transition from Draft to Review

DocumentReview.xml
<Process Name="DocumentReview">    <Activities>        <Activity Name="Draft" IsInitial="true">            <Designer X="100" Y="200"/>        </Activity>        <Activity Name="Review">            <Designer X="400" Y="200"/>        </Activity>    </Activities>    <Transitions>        <Transition Name="Draft_To_Review"                    From="Draft" To="Review"                    Classifier="NotSpecified">            <Triggers>                <Trigger Type="Auto"/>            </Triggers>            <Conditions>                <Condition Type="Always"/>            </Conditions>            <Designer/>        </Transition>    </Transitions></Process>

The trigger is defined as a nested <Triggers> element, not as an attribute on the transition. In the example above, the trigger type is Auto, which means the transition fires automatically when the process instance arrives at the source activity Draft, without any command call.

Conditions are defined as a nested <Conditions> element. Each condition can be of type Always (always passes), Action (a named C# method), Expression, or Otherwise (a fallback). Without at least one condition, the transition never fires. Even an auto-triggered transition needs a condition to pass.

Accessing transitions from code

You can inspect transitions programmatically from the scheme definition. A ProcessInstance holds a reference to its scheme through ProcessScheme, which provides methods to find specific transitions:

var scheme = processInstance.ProcessScheme;// Find a transition by namevar approveTransition = scheme.FindTransition("ApproveReview");// Find all transitions between two activitiesvar transitions = scheme.FindTransitions(    fromActivity, toActivity);// Get all transitions that leave the current activityvar outgoing = scheme.GetPossibleTransitionsForActivity(    currentActivity);

Each method returns a TransitionDefinition object or a list of them, which you can then inspect for properties like trigger type, conditions, and restrictions.

See also

Frequently asked questions

What is a transition in Workflow Engine?

A transition connects two activities in a scheme and defines what causes a process instance to move between them. Every transition has a source activity, a target activity, and a trigger that determines when it fires.

What is the difference between Direct and NotSpecified transitions?

Direct and NotSpecified are classifier values that describe the direction of a transition, not how it fires. A Direct transition is a forward transition in the normal workflow flow. NotSpecified means no direction is assigned. How a transition fires (by command, automatically, or by timer) is determined by its Trigger property, not the classifier.

What happens if multiple transitions match the same command?

For non-fork transitions, the runtime first selects an Always transition, then evaluates action or expression conditions in scheme order and uses the first passing transition. If none passes, it uses an Otherwise transition. Fork transitions are handled separately and can create multiple subprocesses.

How do AllowConcatenationType and RestrictConcatenationType work?

For allow restrictions, And requires every allow rule to match, while Or requires any one. For restrict restrictions, And blocks an actor only when every restrict rule matches, while Or blocks an actor when any one matches. Both properties default to And.