Triggers. General information
Triggers are applied in DWKit to organize additional business logic when processing data. By processing data we understand changing, deleting and getting such data. Trigger is a method activated by the server. Its signature is fixed and does not depend on its usage. That is why you can use the same trigger for different cases of business logic.
There are two types of trigger signature:
-
Synchronous trigger:
public TriggerResult SyncTrigger(EntityModel model, List<dynamic> entities,
TriggerExecutionContext context, dynamic options)
{
...
} -
Asynchronous trigger:
public async Task<TriggerResult> AsyncTrigger(EntityModel model, List<dynamic> entities,
TriggerExecutionContext context, dynamic options)
{
...
}
If synchronous methods are called in trigger, use synchronous triggers. For asynchronous methods use asynchronous triggers.
Trigger result (returned value)
Trigger must return class instance TriggerResult
, its operation can be completed in one of the following ways:
return TriggerResult.Success();
- means that trigger was completed successfully. If trigger is executed in a trigger chain, it will be continued.return TriggerResult.Terminate("Error message");
- trigger will be completed with throwing an exception with a message passed to theTerminate
function. If trigger is executed in a trigger chain, it will be interrupted.return TriggerResult.ValidationFailed(validationResult, "Server validation failed!");
- is used for server validation when changing data. Validation resultvalidationResult
and message will be returned to the client side and displayed in the interface. If trigger is executed in a trigger chain, it will be interrupted.return TriggerResult.Result(resultObj, terminate: true);
- is used for state change of the client side.resultObj
- may be whether a dynamic object, or an anonymous type object. It will be serialized in JSON and applied as delta for global state of the client application. If you've got react components in your application, which react to global state (for example,<StateBindedForm/>
), the result will immediately be displayed in your UI.terminate: true
- means that if a trigger is executed in a trigger chain, it will be interrupted.return TriggerResult.Result(resultObj)
-resultObj
operation is similar to the previous call. But if trigger is executed in a trigger chain, it will be continued.return TriggerResult.Result("Some error message", terminate: true);
- message passed to this method will be displayed in client interface as a pop-up message. We setterminate: true
, and if a trigger is executed in a trigger chain, it will be interrupted.return TriggerResult.Result("Some info message");
- message passed to this method will be displayed in client interface as a pop-up message. If a trigger is executed in a trigger chain, it will be continued.return TriggerResult.Result(new {message = "Some error message", details = "Some error details"}, terminate: true);
- message passed to this method will be displayed in client interface as a pop-up message. Details will be recorded in the browser console. We setterminate: true
, and if a trigger is executed in a trigger chain, it will be interrupted.
Parameters transferred to trigger
DWKit always transfers the following parameters to trigger:
-
EntityModel model
- model description of the items which are transferred through theentities
parameter. In other words, metadata. -
List<dynamic> entities
- entity set trigger is applied to. Depending on the trigger call method, it can contain an item for the whole form (main form + collections) or records for the collection elements.dynamic
in this case always means the instance ofDynamicEntity
class, that is why you can turndynamic
intoDynamicEntity
and vice versa in your code, and work with it in any form you like. No negative change takes place when adducting types. Both forms are equal.dynamic dynamicForm = entities.First();
DynamicEntity dynamicEntityForm = dynamicForm as DynamicEntity;
dynamic dynamicForm = dynamicEntityForm as dynamic; -
TriggerExecutionContext context
- if triggers are executed in chains, context is transferred between them. You can insert parameter value into this context.context.SetParameter("Name", value);
and read this value in triggers which will be executed later in the chain.
var value = context.GetParameter<SomeType>("Name");
You can also check whether a certain parameter exists in the context.
bool exists = context.ContainsParameter("Name");
-
dynamic options
- additional parameter transferred to trigger. Its value is set as JSON in the Admin Panel. We'll talk about it below. For example, these could be trigger settings, with which you can use the same code differently.
Writing trigger code
As we have stated above, there are two locations you can write your trigger code in. These are:
- Code Actions section in the Admin Panel.
- In project code in the class inherited from
IServerActionsProvider
.
Trigger types categorized by calling method
Trigger type, which defines its calling method, is set for each trigger in the Admin Panel interface. Triggers for the main entity and collections are set in the Mapping form and data interface. DWKit offers the following types of triggers:
- Validate - is called for change data operations (Insert, Update, Delete). This trigger will always be activated first, before opening the transaction, that is why it's better be placed in the server validation.
- BeforeTransaction - is called for change data operations (Insert, Update, Delete). Will be activated before opening the transaction by DWKit ORM.
- AfterTransaction - is called for change data operations (Insert, Update, Delete). Is activated immediately after the commit transaction by DWKit ORM.
- BeforeBatch - is called for change data operations (Insert, Update, Delete). Is activated during the transaction, but always before database queries, i.e. before actual data change.
- AfterBatch - is called for change data operations (Insert, Update, Delete). Is activated during the transaction, but always before database queries, i.e. after actual data change.
- BeforeInsert - will be called if in the saved data there is data which needs to be inserted into the database. It is called before insert query in the database.
- AfterInsert - will be called if in the saved data there is data which needs to be inserted into the database. It is called after insert query in the database.
- BeforeUpdate - will be called if in the saved data there is data which needs to be updated in the database. It is called before update query in the database.
- AfterUpdate - will be called if in the saved data there is data which needs to be updated in the database. It is called after update query in the database.
- BeforeDelete - will be called if in the saved data there is data which needs to be deleted from the database. It is called before delete query in the database.
- AfterDelete - will be called if in the saved data there is data which needs to be deleted from the database. It is called after delete query in the database.
- AfterSelect - is called after items were received from the database. You can change received data in the trigger of this type. It is activated only when getting data.
- AfterNew - is called after a new item was created on the server, but before its transferral to the client. You can fill in initial values for new items in this trigger.
- AfterCopy - is called when copying an existing item on server, but before its transferral to the client. You can change item fields in this trigger. It is called after calling the AfterSelect trigger.
Not all trigger types are always available. For the forms without main entity the following triggers are available: Validate, BeforeTransaction, AfterTransaction, BeforeBatch and AfterBatch. Triggers available for collections: BeforeInsert, AfterInsert, BeforeUpdate, AfterUpdate, BeforeDelete, AfterDelete and AfterSelect.
Defining triggers for forms
Triggers are set in the Mapping form and data interface of the Admin Panel. In this interface you
can set which triggers will be activated for the main entity and collections, set trigger calling method, choose triggers to be called and
set options
parameter as JSON. Triggers are set for every collection individually. Trigger type is set in the Triggers input (you can
choose several methods for one trigger) and trigger method name in the Action input. The object transferred into the options
parameter
is set in the Parameter input.