About Flow Behavior
  • Updated on 11 Dec 2013
  • 5 minutes to read
  • Print
  • Dark
    Light

About Flow Behavior

  • Print
  • Dark
    Light

Overview

Flows in Decisions can be assigned something called a Flow Behavior . A Flow Behavior acts like an interface definition for a flow. It can enforce expected inputs and outputs as well as create the expected inputs when the behavior is assigned.


Example

To create a new flow behavior create a public class that inherits fromDefaultFlowBehavior . This will provide you with a number of methods and properties which you can override to create your flow behavior.

Flow behavior methods.

 public virtual void OnBehaviorAssigned(Flow f)
public virtual DataDescription[] ProcessInputDeclaration(Flow flow, DataDescription[] inputData);
public virtual void ProcessInputValues(Flow flow, FlowStateData data);
public virtual DataDescription[] ProcessStepInputDeclaration(FlowStep step, DataDescription[] inputs);
public virtual FlowStepToolboxInformation[] ProcessSteps(Flow flow, string[] nodes, FlowStepToolboxInformation[] steps);
public virtual ValidationIssue[] RunFlowValidation(Flow flow);

OnBehaviorAssigned Description: This code is run when the behavior is assigned to a flow. You can use this method to make any kind of manipulation to the flow that you want. An example (shown below) might be to add input data to your flow. Another use (also shown below) might be to add a tag to the flow so that you can easily find all flows with your behavior.

Default Behavior: Nothing is done
Example Override of this Method:

 public override void OnBehaviorAssigned(Flow f)
{
   //Set inputs on this flow
   List<flowinputdatadescription> inputs = new List<flowinputdatadescription>();
   DecisionsType decTypeString = new DecisionsNativeType(typeof(string));
   inputs.Add(FlowInputDataDescription.Create(new DataDescription(decTypeString, INPUT_NAME_USER_ID)));
   f.Input = inputs.ToArray();

   //Set tag on this flow
   AbstractUserContext userContext = new SystemUserContext();
   tring flowBehaviorTag = "My Sample Behavior Flow";

   string[] existingTags = TaggingService.Instance.GetTags(userContext, f.Id, typeof(ElementRegistration).FullName);
   {
       if (ArrayUtilities.IsEmpty(existingTags) || !existingTags.Contains(flowBehaviorTag))
       {
           TaggingService.Instance.AddTag(userContext, f.Id, typeof(ElementRegistration).FullName, typeof(ElementRegistration).Name, flowBehaviorTag);
       }
   }
}</flowinputdatadescription></flowinputdatadescription>

ProcessInputDeclaration

Description: This method is used in conjunction with the ProcessInputValues method. In this method you are able to declare special inputs that are only visible inside your flow. Whereas regular inputs get their value from data being mapping into the flow, these inputs get their value from code which is run in the ProcessInputValues method. These inputs are not seen from the outside of the flow, but the data of these inputs is consumable inside the flow. An example use case for this functionality would be one where you only want to hand in only a simple piece of data (like an ID) into a flow, but to have complex data (like the object associated with that id) available in the flow. In this example you want to build a flow behavior that takes in only a user ID, but inside the flow has a full user object available to be used.
Default Behavior: No inputs are modified..
Example Override of this Method

 public override DataDescription[] ProcessInputDeclaration(Flow flow, DataDescription[] inputData)
{
    if (flow == null)
    {
        throw new Exception("flow not specified");
    }
 
    if (inputData == null)
    {
        inputData = new DataDescription[0];
    }

    List<datadescription> inputs = new List<datadescription>(inputData);

    DecisionsType decType = DataStructureService.Instance.GetDecisionsTypeByFullName(new SystemUserContext(), typeof(Account).FullName);
    inputs.Add(new DataDescription(decType, "User Account to Process"));

    return inputs.ToArray();
}</datadescription></datadescription>

ProcessInputValues

Definition: As mentioned above, this method should be used in conjunction with the ProcessInputsDelcaration method. This method is executed at runtime and is used to populate the values of the inputs declared by ProcessInputDeclaration . In the example below, we use the "User Id to Process" input value to look up the value for "User Account to Process".
Default Behavior: Do nothing
Example Override of this Method:

 public override void ProcessInputValues(Flow flow, FlowStateData data)
{
    Account accountToProcess = AccountService.Instance.GetByID(new SystemUserContext(), data["User Id to Process"].ToString());

    data["User Account to Process"] = accountToProcess;
}

RunFlowValidation

Definition: This method returns an array of validation issues. Validation issues are assigned to steps (this is part of the ValidationIssue data type definition). You can use this method to validate anything you want about the flow. An example of how this can be used it to ensure that the flow has the expected inputs
Default Behavior: No validation issues are checked for or returned.
Example Override of this Method:

 public override ValidationIssue[] RunFlowValidation(Flow flow)
{
    // check that the flow only has correct inputs
    List<validationissue> validationIssues = new List<validationissue>();

    if (flow.InputData != null && flow.InputData.Length == 1)
    {
        if (flow.InputData[0].Type is DecisionsNativeType && ((DecisionsNativeType)flow.Input[0].Type).ToNativeType() == typeof(string))
        {
            return validationIssues.ToArray();
        }
    }
    FlowStep startStep = flow.GetStepsOfType(typeof(StartStep)).FirstOrDefault();
    validationIssues.Add(new ValidationIssue(startStep, "This flow must have only one String input"));
    return validationIssues.ToArray();
}</validationissue></validationissue>

In addition to methods, DefaultFlowBehavrior also has properties which can be overridden.

 public virtual bool ConstrainFlowOutputs { get; }
public virtual OutcomeScenarioData[] DefaultOutputs { get; }
public virtual bool IsUserSettable { get; }
public virtual string Name { get; }
public virtual bool OnlySyncSteps { get; }
public virtual string OverrideDebugUIClassName { get; }
public virtual bool ShowFlowInputs { get; }

DefaultOutputs

Description: Allows you to define the expected output paths and output data in those paths. Note: this should be used in conjunction with ConstrainFlowOutputs in order to cause validation warnings when this default is not met.
Default Value: null
Example Override:

 public override OutcomeScenarioData[] DefaultOutputs
{
    get
    {
        return new OutcomeScenarioData[] { 
            new OutcomeScenarioData("Done",new DataDescription[] { new DataDescription(new DecisionsNativeType(typeof(string)), "My Result", false, true, false)}) };
    }
}

ConstrainFlowOutputs

Description: Setting to true causes validation warnings on the end steps on your flow when the end steps' outputs don't match those as defined in the DefaultOutputs property
Default Value: false
Example Override:

 public override bool ConstrainFlowOutputs
{
    get
    {
        return true;
    }
}

IsUserSettable
Description: Sets whether or not this flow behavior shows up in the Decisions Portal UI when a user sets the behavior of a flow. When set to false, this behavior will not show up in the behavior list for users to select from, but can still be used by your code to set flow behaviors on flows.
Default Value: true
Example Override:

 public override bool IsUserSettable
{
    get { return false; }
}

Name
Description: Use this property to give your flow behavior a friendly name. This name will be displayed in the portal UI when a user sets the flow behavior for a flow. If you don't set this, your name will show up as the full class 
Default Value: "Default Flow Behavior"
Example Override:

 public override string Name
{
    get
    {
        return "My Behavior Flow";
    }
}

OnlySyncSteps
Description: This property when set to true forces the flow to only be allowed to contain Sync steps. This should be used on flows where you expect the flow's response to return synchonously.
Default Value: false
Example Override:

 public override bool OnlySyncSteps
{
    get
    {
        return true;
    }
}

OverrideDebugUIClassName
Description: This is an advanced property that allows you to specify a different UI to be presented when the debugger is run. If this is a requirement for you, please contact professional services for help with implementation.
Default Value: null

ShowFlowInputs

Description: When set to true, this property hides the Inputs section of the flow's property editor. This can be used to block Designers from editing the inputs that you have defined in your flow behavior.
Default Value: true
Example Override:

 public override bool ShowFlowInputs
{
    get
    {
        return false;
    }
}
Was this article helpful?