Actions¶
Actions are the building blocks for providing behavior using workflows. Actions are designed to be modular, and unit-testable, they can be thought of lego-pieces, used alone or in combination with other actions, to satisfy business requirements.
Actions can be given arguments. Arguments are primitive data types which can be bound either from the entity's properties, from invocation parameters, or can be constant values defined by the user at workflow configuration time. See here to learn more about action arguments.
Actions can also get access to the current workflow domain entity's instance to
act on it. Actions can inject services through DI, and other specific
dependencies such as MassTransit's IPublishEndpoint
can be accessed through
IActionHandlerContext
, as well.
Action descriptors¶
Workflow actions are described by means of IWorkflowActionDescriptor
instances.
Suite framework provides WorkflowActionDescriptor<THandler>
base class, from
which you should use for describing your workflow actions.
Descriptors provide information to identify the action and the handler type, and any argument required by the action to get executed.
The action handler provides the workflow behavior by updating the entity's instance and/or by orchestrating other services through publishing messages.
Note
We recommend you to gather all the information describing the action inside a single class, meaning that the handler class would be defined as inner class inside the descriptor itself, in order to easily locate the descriptor's related handler.
Registering actions¶
Workflow actions must be added to the workflow module options before they are used by
workflow templates. The module options instance requires the corresponding
WorkflowActionDescriptor
type argument when invoking the AddWorkflowAction
method to do so:
Action identifier¶
The Id
property is intended to provide a unique id among the whole ecosystem.
We encourage you to use a namespace-like notation, such as
{your-bounded-context-name}Actions/{action-id}
. For example, for ServiceOrders
bounded context, the actions id should start with ServiceOrderActions
.
Action handlers¶
You'll typically need access to entity's instance to provide workflow behavior.
In that case, you'll need to implement IWorkflowActionHandler{TInstance}
,
which let you access to the entity's instance at runtime, to get or update it's
properties. Take into account that any update on the instance properties will be
persisted upon current unit of work completion.
In the other hand, IWorkflowActionHandler
interface implementation is intended
to provide behavior that do not require access to the entity's instance. You're
unlikely to found yourself doing that. This is something rather done by
framework developers.
Important
IWorkflowActionHandler
implementations can be shared across workflows defined
for different entities, whereas IWorkflowActionHandler{TInstance}
doesn't, because
they are designed to work with workflows of TInstance
type.
IWorkflowActionHandlerContext
and IWorkflowActionHandlerContext{TInstance}
¶
Action context has properties and methods to build the workflow logic:
Instance
property: let you access to the entity's instance (only available forIWorkflowActionHandlerContext{TInstance}
).GetArgument<TArgType>(argName)
method let you access argument values, using the binding type configured for the current workflow.GetPublishEndpoint()
extension method let you access the current publish endpoint, from the current scope.
Action descriptor example¶
Here below you can see a complete example of an action descriptor with its action handler implementation (inner class).