Scheme inlining
These functions are available in the Workflow Engine ≥ 4.0
Scheme inlining is embedding one scheme into another. You can check almost any scheme as available for inlining and then embed it into other schemes. First of all such mechanism is necessary to re-use typical scheme segments. Inlining is embedding one scheme into another one. The scheme the process will work with is the result of transferring objects of the scheme which is being inlined (inlined scheme) into the scheme, code of which is used to create the process (target scheme).
Inlined scheme is checked as available for inlining in the designer. There's a special button for this in the toolbar.
There are two required conditions for the scheme to be inlined:
- there must be only one Initial Activity in the scheme.
- there must be at least one Final Activity in the scheme.
Once you have checked the scheme as available for inlining (can be inlined), you must save it. To embed the inlined
scheme into the target scheme do the following: when editing the target scheme add Inline Activity by clicking
the appropriate button in the Elements
panel.
After Inline Activity has been added into the scheme, it works the same way as any typical Activity, which means that transitions can enter and exit it normally.
One of the key differences is that Inline Activity has only two properties:
Name
- inline name.Inline scheme
- inlined scheme code.
When embedding the inlined scheme into the target scheme, transitions belonging to the target scheme are relinked
to the Activities of the inlined scheme. Transitions entering the inlined scheme (i.e. transitions into the
relevant Inline Activity) will be completed in the initial activity of the inlined scheme. Transitions exiting the
inlined scheme (transitions out of the relevant Inline Activity) will start in the first final activity of the
inlined scheme, if the Inlined Final Activity Name
field has not been filled for these transitions. If
the Inlined Final Activity Name
field has been filled, these transitions will start in the appropriate Activity of
the inlined scheme.
When the target scheme is saved in the designer, the designer checks whether it is possible to combine target scheme and inlined scheme. If not, error is displayed. Workflow Engine supports multi-level inlining when one scheme is inlined into another, and this other scheme is in its turn inlined into the third scheme. There can be an unlimited number of Inline Activities connected to any inlined schemes in the target scheme.
Database (Persistence) Providers and inlining
Two columns were added into the WorkflowScheme
table to ensure correct inlining:
CanBeInlined
- signifies that the scheme can be inline into other schemes.InlinedSchemes
- is a list of schemes that are inlined into the current scheme. This field is in JSON array format, for example:["ThirdSimpleInline", "SecondSimpleInline", "FirstSimpleInline"]
.
Inlining algorithm
Inlining is executed via special system build step. When embedding the inlined scheme into the target scheme the following transformations of the inlined scheme elements take place:
- Process parameters - are transferred from the inlined into the target unchanged; if there is already a similar parameter in the target (parameters names are compared), parameter type compatibility check is run. If incompatible, an error will be displayed.
- Commands - are transferred from the inlined into the target unchanged; if there is already a similar command in the target (commands names are compared), command parameter compatibility check is run. Missing command parameters are added from the inlined into the target. Common command parameters must be linked to the same process parameter. If incompatible, an error will be displayed.
- Timers - are transferred from the inlined into the target unchanged; if there is already a similar timer in the target (timer names are compared), compatibility check is run. Timers are deemed compatible if all their properties match. If incompatible, an error will be displayed.
- Localizations - are transferred from the inlined into the target unchanged; if there is already a similar localization record in the target (localization record ObjectName, Type and Culture are compared), compatibility check is run. Localization records are deemed compatible if all their properties match. If incompatible, an error will be displayed.
- CodeActions - are transferred from the inlined into the target and are renamed, the rest of the properties remain unchanged. Links to code actions are replaced with new ones in activities, transitions and actors of the inlined scheme.
- Actors - are transferred from the inlined into the target and are renamed; if the
Rule
property was linked to the Code action from the inlined scheme, the link will be replaced with the new name, the rest of the properties remain unchanged. - Activities - are transferred from the inlined into the target and are renamed. If the record in
the
Implementation
orPreExecutionImplementation
was linked to the Code action from the inlined scheme, the link will be replaced with the new name. TheIsInitial
property is always defined false. TheIsFinal
property defined false, if there is at least one transition from this Activity in the result scheme. The rest of the properties remain unchanged, including theState
property. - Transitions - are transferred from the inlined into the target and are renamed. If there are Action type conditions in the transition, and they were linked to the Code action from the inlined scheme, the link will be replaced with the new name. If there are restriction in the transition, and they were linked to Actors from the inlined scheme, the link will be replaced with the new name. Transitions are relinked to new Activities created in the previous step.
We have deliberately not described the CodeActions, Actors, Activities and Transitions renaming algorithm, as new names are too complex (especially in case of multi-level inlining), and the renaming algorithm might change. Instead, we have added several properties into each element, which make it searchable, if you know element original name in the inlined scheme. They are described in the next section.
CodeActions, Actors, Activities and Transitions additional properties
Use the following attributes to search for inlined elements of the scheme:
CodeAction element property
Hereby codeActionDefinition
is an object of the CodeActionDefinition
type. Get the code actions list:
List<CodeActionDefinition> codeActions = processInstance.ProcessScheme.CodeActions;
Additional properties:
codeActionDefinition.WasInlined
- will return true, if this element was inlined when building the scheme.codeActionDefinition.OriginalName
- Code Action name in the inlined scheme.codeActionDefinition.OriginalSchemeCode
- the inlined scheme code, i.e. the code of the scheme the Code Action originally belonged to.
Actor element properties
Hereby actorDefinition
is an object of the ActorDefinition
type. Get the actors list:
List<ActorDefinition> actors = processInstance.ProcessScheme.Actors;
Additional properties:
actorDefinition.WasInlined
- will return true, if this element was inlined when building the scheme.actorDefinition.OriginalName
- Actor name in the inlined scheme.actorDefinition.OriginalSchemeCode
- the inlined scheme code, i.e. the code of the scheme the Actor originally belonged to.
Activity element properties
Hereby activityDefinition
is an object of the ActivityDefinition
type. Get the activities list:
List<ActivityDefinition> activities = processInstance.ProcessScheme.Activities;
Additional properties:
activityDefinition.WasInlined
- will return true, if this element was inlined when building the scheme.activityDefinition.OriginalName
- Activity name in the inlined scheme.activityDefinition.OriginalSchemeCode
- the inlined scheme code, i.e. the code of the scheme the Activity originally belonged to.activityDefinition.FirstTimeInlineName
- name of the Inline Activity instead of which the element was inlined for the first time.activityDefinition.LastTimeInlineName
- the name of the Inline Activity instead of which the element was inlined for the last time. This value will be equal toactivityDefinition.FirstTimeInlineName
for one-level inlining.
Transition element properties
Hereby transitionDefinition
is an object of the TransitionDefinition
type. Get the transitions list:
List<TransitionDefinition> transitions = processInstance.ProcessScheme.Transitions;
Additional properties:
transitionDefinition.WasInlined
- will return true, if this element was inlined when building the scheme.transitionDefinition.OriginalName
- Transition name in the inlined scheme.transitionDefinition.OriginalSchemeCode
- the inlined scheme code, i.e. the code of the scheme the Transition originally belonged to.transitionDefinition.FirstTimeInlineName
- name of the Inline Transition instead of which the element was inlined for the first time.transitionDefinition.LastTimeInlineName
- the name of the Inline Transition instead of which the element was inlined. for the last time. This value will be equal totransitionDefinition.FirstTimeInlineName
for one-level inlining.
Scheme versioning and inlining
When the inlined scheme is saved in the designer, the IsObsolete
property will be automatically applied to all linked
schemes. This link is defined by the InlinedSchemes
field in the WorkflowScheme
table. Use the following code to
specify the IsObsolete
property manually:
var runtime = WorkflowInit.Runtime;
var codesForObsolete = runtime.Builder.GetRelatedByInliningSchemeCodes(schemeCode);
runtime.SetSchemeIsObsolete(schemeCode);
if (codesForObsolete != null)
{
foreach (var code in codesForObsolete)
{
runtime.SetSchemeIsObsolete(code);
}
}
Thus, you can get the linked schemes code list by calling
the runtime.Builder.GetRelatedByInliningSchemeCodes(schemeCode)
method.
Inlining Parameters Mapping
This feature is available in the Workflow Engine ≥ 16.0.0
In the Inline Activity settings, you can configure parameter mapping between the parent scheme and the inlined scheme. Essentially, this is a set of rules that specify the target parameter name and the expression used to calculate its value. These rules are applied in the first implementation of the inlined scheme’s initial activity for input parameters and in the final implementation for output parameters.
For each mapping rule, the expression is first evaluated, and then the result is assigned to the target parameter using the
processInstance.SetParameter
method. The parameter’s purpose is specified only if the target parameter is not defined in either the
inlined or parent scheme.
Example of configuring parameter mapping using the process definition builder:
processDefinitionBuilder
.CreateInlineActivity("MyInlineActivity", "MyInliningScheme")
.SetInputParameters(
new("InlinedStringParameter", "\"Value\""),
new("InlinedIntParameter", "@ParentIntParameter + 10")
)
.SetOutputParameters(
new("ParentStringParameter", "@(InlinedStringParameter).Trim()", ParameterPurpose.Persistence),
new("ParentIntParameter", "@InlinedIntParameter"),
new("InlinedStringParameter", "null")
);
In this example, the following mapping rules are defined for the MyInliningScheme
scheme:
InlinedStringParameter
- the parameter value will be the literal"Value"
.InlinedIntParameter
- the parameter value will be the value of the parent scheme’sParentIntParameter
increased by 10.ParentStringParameter
- the parameter value will be the result of calling theTrim
method on the value ofInlinedStringParameter
. This value will be saved to the database even if the parameter is not defined in either the parent or inlined scheme.ParentIntParameter
- the parameter value will be equal to the value ofInlinedIntParameter
.InlinedStringParameter
- the parameter value will be deleted from the process.
You can also configure parameter mapping using the designer. To do this, open the Inline Activity settings and add or modify parameters in
the Input Parameters
and Output Parameters
sections.