Workflow Analyzer is a tool for making sure your project follows best practices, maintainability, readability, performance, reusability, reliability, and security requirements.
These concepts are important for ensuring clean and reliable workflows that can sum up large automation projects.
Note:
To build custom rules, you need the UiPath.Activities.Api package from the Official feed. The SDK package must be used as a development dependency in your custom project. Read more about Development Dependencies.
Watch the video below to get step-by-step instructions on how to build custom rules, and how to create custom activities with the Activity Creator extension.
In its off-the-shelf form, Workflow Analyzer is integrated into Studio and incorporates validation and analyzer capabilities. Analysis cannot be done if validation returns errors.
Workflow Analyzer Concepts
In order to build custom rules for your project, a number of concepts should be defined to better understand how Workflow Analyzer works behind the scenes.
Important!
When building custom rules, please target the .NET Framework version 4.6.1.
Rules and Counters
Workflow Analyzer makes use of certain criteria to ensure project reliability is met. These checks are performed using carefully defined rules and counters.
A rule represents a requirement that must be met. It can be set to check the inspection object against the rule definition.
A counter represents a check done for revealing the number of times a particular event or condition has occurred.
For each unmet rule, a message is listed in the Error List panel in the form of a warning, error, info, or verbose messages. These listings also contain recommendations for making changes and ensuring rules are met.
Note:
When creating custom rules and counters, make sure to follow the naming convention detailed in the About Workflow Analyzer page.
Inspection Object
Workflow Analyzer is capable of performing an in-depth analysis of a predefined object. The object represents the scope to be analyzed, the area in which the rule or counter is enforced.
- Activity: it is the smallest inspection object. For example, Variables Naming Convention, Variable Length Exceeded, and File Activities Stats are three out-of-the-box rules that can be set to inspect activities.
- Workflow: rules or counters may be set to perform checks in just a single project file. High Arguments Count and Empty Sequence are just two predefined rules that have workflow as their scope.
- Project: checks are performed at the project level, ensuring project reliability is met. Unused Dependencies is a rule applied at the project scope.
Creating Rules
From the Official feed (https://www.myget.org/F/workflow
), install the UiPath.Activities.Api package.
To help you create a custom rule, let's look at a current predefined rule in the Workflow Analyzer, Variable Length Exceeded. This rule checks whether the length of variables defined in the project is smaller than 20 characters. The rule's inspection object is activity.
Behind the scenes, the rule looks like this:
// This static class is not mandatory. It just helps organizining the code.
internal static class VariableLengthRule
{
// This should be as unique as possible, and should follow the naming convention.
private const string RuleId = "ST-NMG-008";
internal static Rule<IActivityModel> Get()
{
var rule = new Rule<IActivityModel>("Variable Length Rule", RuleId, Inspect)
{
RecommendationMessage = Recommendation,
/// Off and Verbose are not supported.
ErrorLevel = System.Diagnostics.TraceLevel.Warning
};
return rule;
}
// This is the function that executes for each activity in all the files. Might impact performance.
// The rule instance is the rule provided above which also contains the user-configured data.
private static InspectionResult Inspect(IActivityModel activityModel, Rule ruleInstance)
{
var messageList = new List<string>();
foreach(var activityModelVariable in activityModel.Variables)
{
if (activityModelVariable.DisplayName.Length > 20)
{
messageList.Add($"The variable {activityModelVariable.DisplayName} has a length longer than 20");
}
}
if (messageList.Count > 0)
{
return new InspectionResult()
{
ErrorLevel = ruleInstance.ErrorLevel,
HasErrors = true,
RecommendationMessage = ruleInstance.RecommendationMessage,
// When inspecting a model, a rule can generate more than one message.
Messages = messageList
};
}
else
{
return new InspectionResult() { HasErrors = false };
}
}
}
The RuleId
parameter requires the name of your rule. In this example, the Variable Length Exceeded rule carries the ST-NMG-008
rule ID and follows the Rule Naming Convention.
The RecommendationMessage
parameter requires a message to be displayed as a recommendation to help the user solve any inconsistencies found after the analysis is done. The message should be succinct and offer clear steps.
The ErrorLevel
parameter states the default action to be taken in case the condition isn't met. In this example, the rule throws a warning. Default actions can be error, warning, info or verbose.
Build rules with parameters
The situation changes slightly when we want to build rules that contain customizable parameters. One of such rules is Variables Naming Convention. Its inspection element is activity and carries a default Regex expression, which can be changed.
Behind the scenes, this rule looks like this:
internal static class VariableNamingRule
{
private const string RuleId = "ST-NMG-001";
private const string RegexKey = "Regex";
private const string DefaultRegex = @"^([A-Z]|[a-z])+([0-9])*$";
internal static Rule<IActivityModel> Get()
{
var rule = new Rule<IActivityModel>(Strings.ST_NMG_001_Name, RuleId, Inspect)
{
RecommendationMessage = Recommendation,
ErrorLevel = System.Diagnostics.TraceLevel.Warning
};
rule.Parameters.Add(RegexKey, new Parameter()
}
private static InspectionResult Inspect(IActivityModel activityModel, Rule ruleInstance)
{
// This retrieves the parameter value from the rule instance as configured by the user, if not, the default value.
var setRegexValue = ruleInstance.Parameters[RegexKey]?.Value;
var regex = new Regex(setRegexValue);
var messageList = new List<string>();
foreach (var activityModelVariable in activityModel.Variables)
{
if(!regex.IsMatch(activityModelVariable.DisplayName))
{
messageList.Add(string.Format(Strings.ST_NMG_001_ErrorFormat, activityModelVariable.DisplayName, setRegexValue));
}
}
if(messageList.Count > 0)
{
return new InspectionResult()
{
ErrorLevel = ruleInstance.ErrorLevel,
HasErrors = true,
RecommendationMessage = ruleInstance.RecommendationMessage,
Messages = messageList
};
}
else
{
return new InspectionResult() { HasErrors = false };
}
}
}
Notice it calls the RuleId
, RegexKey
and DefaultRegex
which is the default Regex expression associated with this rule.
The RecommendationMessage
and ErrorLevel
parameters are the same as for the previously presented rule.
Build Counters
Counters represent checks done for revealing the number of times a particular event or condition has occurred.
Their structure is a bit different from that of rules, in the sense that the only available ErrorLevel
parameter for counters is Info
. Therefore, the expression for defining the error level for a counter should look like this ErrorLevel = System.Diagnostics.TraceLevel.Info
.
Let's take File Activities Stats as an example of how counter rules look behind the scenes:
internal static class NumberOfActivitiesInFile
{
private const string RuleId = "ST-ANA-009";
internal static Counter<IActivityModel> Get()
{
return new Counter<IActivityModel>(Strings.ST_ANA_009_Name, RuleId, Inspect);
}
// A Counter<T> receives the entire collection of T objects in the parent structure. e.g. activities in workflow, workflows in project.
private static InspectionResult Inspect(IReadOnlyCollection<IActivityModel> activities, Counter ruleInstance)
{
return new InspectionResult()
{
// For a counter, the error level is always info, even if not set here.
ErrorLevel = System.Diagnostics.TraceLevel.Info,
// For a counter, the Has Errors field is always ignored.
HasErrors = false,
Messages = new List<string>() { string.Format(Strings.ST_ANA_009_ErrorFormat, activities.Count) }
};
}
Build Rules for StudioX
By default, rules only apply to the Studio profile. To make a rule appear in the StudioX profile as well, add the ApplicableScopes
property and configure it to include BusinessRule
. For example, you can add the property like this:
var rule = new Rule<IActivityModel>(Strings.ORG_USG_001_Name, RuleId, Inspect)
{
RecommendationMessage = Strings.ORG_USG_001_Recommendation,
ErrorLevel = TraceLevel.Error,
//Must contain "BusinessRule" to appear in StudioX, rules always appear in Studio
ApplicableScopes = new List<string> { RuleConstants.BusinessRule }
};
Rules Registration
Registration Interface Method
Please bear in mind that by using this method, your package is compatible only with Studio versions 2019.10 or higher.
Implement the IRegisterAnalyzerConfiguration
interface with the following method Initialize(IAnalyzerConfigurationService workflowAnalyzerConfigService)
.
using UiPath.Studio.Activities.Api;
using UiPath.Studio.Activities.Api.Analyzer;
using UiPath.Studio.RulesLibrary.Rules.Naming;
namespace UiPath.Studio.RulesLibrary
{
public class RegisterAnalyzerConfiguration : IRegisterAnalyzerConfiguration
{
public void Initialize(IAnalyzerConfigurationService workflowAnalyzerConfigService)
{
// Naming
workflowAnalyzerConfigService.AddRule(VariableNamingRule.Get());
workflowAnalyzerConfigService.AddRule(DisplayNameDuplicationRule.Get());
workflowAnalyzerConfigService.AddRule(VariableNameDuplicationRule.Get());
workflowAnalyzerConfigService.AddRule(ArgumentNamingRule.Get());
workflowAnalyzerConfigService.AddRule(VariableLengthRule.Get());
}
}
}
Note:
Call the
HasFeature
method on theIAnalyzerConfigurationService
to register rules for a specific Studio version.
IRegisterMetadata Method
Please note that this method is available only for Studio versions higher than 2019.6, and it's not as suitable as the registration interface method.
- Add a method void
Initialize(object api)
to your implementation ofIRegisterMetadata
. - In your
Initialize
implementation cast theobject
parameter toWorkflowDesignApi
, and add everything under a Try Catch just to make sure any exceptions are managed. - Once you resolve the
WorkflowDesignApi
, theWorkflowAnalyzerConfigService
is available as a property. - At this point, you have access to the
IAnalyzerConfigurationService
detailed in the section above.
Add Rules to Studio
Custom Workflow Analyzer rules can be integrated in Studio in two ways:
- at global level by adding the external assembly (.dll) in the Studio install location
- at project level by installing the custom activities pack.
At Global Level
To make custom rules available in all the projects created in your instance of Studio, you must add the external assembly (.dll) packages to a specific folder from which Studio loads custom rules. By default, the folder path is:
.msi
:C:\Program Files\UiPath\Studio\Rules
.exe
: `%localappdata%\UiPath\app-%version%\Rules
Optionally, you can change the folder from which Studio loads custom rules by going to Home (Studio Backstage View) > Settings > Locations and defining a Custom Workflow Analyzer rules location.
Follow the steps detailed in the Creating a Custom Activity page to export the code as a .dll file.
At Project Level
To make custom rules available only for a certain project, create a NuGet package (.nupkg
) and install it in a Studio project as a dependency, as detailed here.
Updated 2 years ago