Plugin System
The plugin system packages common workflow patterns as IWorkflowPlugin assemblies. Plugins auto-register actions, rules, custom activities, conditions, autocomplete, parameter formats, and external parameter providers with the runtime. Basic, Approval, and Loop ship in the Core package; Files, Active Directory, Real-Time Tracking, BPMN, and Forms ship as separate NuGet packages. Register each one with runtime.WithPlugin() before runtime.Start().
Without a plugin system, every common workflow pattern - sending an email, routing an approval chain, assigning a task to a user - requires hand-written action code in every project. Developers write the same HTTP client, the same approval logic, the same task inbox queries, project after project.
The plugin system is a set of pre-built workflow capabilities packaged as .NET assemblies that register with the runtime at startup. A plugin can provide actions, conditions, rules, Designer formats, custom activities, or runtime hooks; its implemented provider interfaces determine the capabilities it exposes.
With the plugin system, you install a NuGet package or reference its assembly, then register the plugin during runtime configuration. For example, ApprovalPlugin adds approval-history and inbox/outbox actions and maintains their provider records. BasicPlugin supplies the separate approver-list and completion logic used in multi-user approval patterns.
What it is
Think of a plugin as a pre-assembled toolkit for a specific workflow capability. ApprovalPlugin, for example, exposes generated Designer activity wrappers for its query actions and connects those actions to approval persistence. The runtime knows how to execute the wrappers because WithPlugin registers the plugin's provider interfaces during configuration.
The following plugins ship with Workflow Engine. Basic, Approval, and Loop live in the Core package; the others ship as separate NuGet packages.
| Plugin | NuGet package | What it provides |
|---|---|---|
| Basic | WorkflowEngine.NETCore-Core | HTTP request and email actions, process creation, command, state and parameter actions, approver lists, basic conditions and rules |
| Approval | WorkflowEngine.NETCore-Core | Approval history, per-identity inbox records, and derived outbox summaries |
| Loop | WorkflowEngine.NETCore-Core | For and ForEach loop patterns for repeating activities and subprocess iteration |
| Files | WorkflowEngine.NETCore-FilesPlugin | File and directory operations, file lists, archives, and FTP transfer |
| Active Directory | WorkflowEngine.NETCore-ActiveDirectoryPlugin | User and group lookup from Active Directory for rule evaluation |
| Real-Time Tracking | WorkflowEngine.NETCore-RealTimeTrackingPlugin | Real-time process state updates via SignalR |
| BPMN | WorkflowEngine.NETCore-BpmnPlugin | Import of BPMN 2.0 XML files into Workflow Engine schemes |
| Forms | WorkflowEngine.NETCore-FormsPlugin | Forms bound to activities, drafts, and form command execution |
All plugins follow the same registration pattern:
runtime.WithPlugin(new BasicPlugin()) .WithPlugin(new ApprovalPlugin()) .WithPlugin(new RealTimeTrackingPlugin());Each call to WithPlugin first detects and registers the provider interfaces implemented by the plugin. It then adds the plugin to the runtime and calls IWorkflowPlugin.OnPluginAdd for plugin-specific handlers, build steps, or other setup. The runtime aggregates the registered capabilities for the execution engine and Designer API.
For developers: Every plugin implements IWorkflowPlugin, which defines Name, Disabled, OnPluginAdd(WorkflowRuntime, List<string>), and OnRuntimeStartAsync(WorkflowRuntime). The runtime auto-detects the plugin's capabilities when it implements any of these interfaces:
IWorkflowActionProvider- registers actions and conditions for use in schemesIWorkflowRuleProvider- registers actor and role resolution rulesICustomActivityProvider- registers custom activity types that appear in the Designer paletteICustomConditionProvider- registers custom condition types for transitionsIDesignerParameterFormatProvider- registers custom parameter format providers for Designer property panelsIDesignerAutocompleteProvider- registers autocomplete suggestions for code action editorsIWorkflowExternalParametersProvider- registers external parameter lookups for process parameters
The runtime auto-detects these interfaces during WithPlugin() and registers each with the corresponding With*Provider method. During OnPluginAdd, the plugin can perform additional setup. See the Basic Plugin reference for an example implementation.
Why it matters
The plugin system delivers these outcomes:
- No re-implementation of common capabilities - Approval tracking, email notifications, HTTP calls, and file operations are available through built-in plugins. A project can combine ApprovalPlugin tracking with BasicPlugin approval rules instead of recreating both.
- Consistency across projects - Every team uses the same tested implementation of approval tracking, email sending, and process control. The surface area of custom code shrinks to project-specific actions and rules only.
- Extensible by design - You can write your own plugins that follow the same registration pattern as the shipped plugins. Package custom activities, actions, and conditions as a reuse unit and share them across projects, teams, or tenants.
- Designer integration out of the box - When a plugin registers custom activities through
ICustomActivityProvider, the Designer can display them as palette elements with their registered templates and parameter formats. Business users can add plugin-provided activities to schemes without developer involvement.
Who it is for
Developer: You interact with plugins through the IWorkflowPlugin interface and the runtime.WithPlugin() registration method. For a custom plugin, implement the applicable provider interfaces so WithPlugin can detect them, and use OnPluginAdd for additional runtime setup. See the Basic Plugin implementation for a code example.
Enterprise architect: Plugins can be scoped per scheme - register a plugin with a scheme list and it only provides activities to those schemes. This prevents cross-scheme interference when two workflows use plugins that register activities with the same name. Plugin dependencies (such as Active Directory integration) are managed through standard NuGet package references.
When to use it
Use a plugin when your scheme needs a capability that the plugin provides. Typical examples:
- Tracking approval workflows - Register ApprovalPlugin when an application needs approval history or per-identity inbox and outbox lists. Use BasicPlugin when the scheme must collect several decisions and test a completion threshold.
- Integrating with external systems - A scheme needs to call an HTTP API, send an email, or create a file. Use the Basic plugin's HTTP action or the Files plugin's upload/download actions instead of writing custom action code.
- Looking up identity sources - Scheme rules need to resolve users and groups from Active Directory. Register the Active Directory plugin as the rule provider, and scheme designers can reference AD groups directly in rule definitions.
- Building custom extensions as packages - You have a reusable pattern across multiple projects (for example, a credit-check subprocess with custom activities and rules). Package it as an
IWorkflowPluginassembly, distribute via NuGet or file share, and register withruntime.WithPlugin().
How it compares
The following table compares the Workflow Engine plugin system with the alternative of building every workflow pattern from scratch.
| Approach | What it requires | Result |
|---|---|---|
| Build every pattern from scratch | Write custom activities, actions, conditions, Designer forms, and SVG templates for each pattern. Write and maintain tests for all of them. | High initial cost. Ongoing maintenance across every project. Duplicate implementations of the same patterns. |
| Workflow Engine plugin system | Reference a plugin package, register it with runtime.WithPlugin(), and use its registered capabilities. | Single maintained implementation per pattern. Activities available to any scheme immediately. |
Frequently asked questions
What plugins does Workflow Engine ship, and are they all included with the base license?
The Basic, Approval, and Loop plugins are part of the Core package (WorkflowEngine.NETCore-Core) and do not require a separate license. The Active Directory, BPMN, and Forms plugins need a license that includes them; the Files and Real-Time Tracking plugins do not. See Workflow Engine Editions for per-plugin license mapping.
How do I register a plugin with the runtime?
Call runtime.WithPlugin(instance) during initialization, where instance is an object implementing IWorkflowPlugin. For example: runtime.WithPlugin(new ApprovalPlugin()). The call must happen before runtime.StartAsync(). See Workflow Runtime for the complete configuration chain.
Can I write my own plugin?
Yes. Implement IWorkflowPlugin and the provider interfaces for the capabilities the plugin exposes. WithPlugin detects those interfaces; use OnPluginAdd for additional setup such as handlers or build steps. Package the assembly as a NuGet package or distribute it as a project reference.
Can I load plugins from an external DLL without recompiling?
Yes. Use Assembly.LoadFrom() to load the external assembly, find types implementing IWorkflowPlugin, instantiate each, and call runtime.WithPlugin(). The runtime auto-detects the plugin's capabilities - action providers, rule providers, custom activities, and conditions - and integrates them into the Designer and execution engine.
Can I restrict a plugin to specific schemes?
Yes. WithPlugin accepts an optional list of scheme codes. It passes the list to action, rule, Designer parameter-format, and autocomplete registration. Custom activity types, custom condition forms, and external parameter providers are registered without the list; plugin-specific handlers and build steps decide separately whether to honor it.