-
Notifications
You must be signed in to change notification settings - Fork 14
Tutorial 04 05 Add Dispatcher Classes
For each traditional Synergy routine exposed by Traditional Bridge, there must be a dispatcher, which is a class that
- deserializes
in
andinout
parameters from JSON-RPC request messages into suitable variables and prepares variables forout
parameters and function return values. - calls the underlying traditional Synergy subroutine or function, passing parameter variables.
- serializes
inout
parameters,out
parameters, and the function return value into a JSON-RPC response message.
Each dispatcher class must inherit from the RoutineStub
class, which is defined in Traditional Bridge library code and has helper methods for serializing/deserializing, exception handling, and logging (see RoutineDispatcher.dbl). We recommend organizing all dispatcher classes in a project folder and a namespace path.
If you create a Traditional Bridge environment from scratch, you will need to create routine dispatcher classes for your methods. But with xfServerPlus migration, code generation creates these classes, as we'll see in the steps that follow.
With xfServerPlus migration, dispatcher classes are generated from definitions in a Synergy method catalog (SMC). In Adding Traditional Synergy Routines, we selected an interface from our sample SMC, so now the code generation feature of the Harmony Core GUI tool will generate dispatcher classes from methods in the selected interface.
-
Open a Windows command prompt and navigate to the directory with the
.sln
file for your Harmony Core solution. Then enter the following command to open the Harmony Core GUI tool:harmonycore gui
-
When the "Loading Solution" message disappears, select
Codegen > Regen
from the menu to generate code for the solution. Then, when the "Finished" message appears at the top of the Regen window, clickOK
. -
In Visual Studio Solution Explorer, right-click the Dispatchers folder in the TraditionalBridge project (TraditionalBridge\Source\Dispatchers) and select
Add > Existing Item
from the context menu. -
In the Add Existing Item window, navigate to the Dispatchers folder (Which is under TraditionalBridge\Source), select the
BridgeMethodsMethodDispatchers.dbl
file, and clickAdd
. (You'll also see aBridgeMethodsDispatcher.dbl
file in this folder. We'll add that file in the next section of this tutorial: Adding the Main Dispatcher Class.)
- Now open
BridgeMethodsMethodDispatchers.dbl
in the Visual Studio editor. Notice that this file has one dispatcher class for each method in theBridgeMethods
interface—i.e., it has a dispatcher for each of our traditional Synergy routines in the Methods folder.
Scroll down to the GetEnvironment_Dispatcher
class. This is a good place to start our examination of dispatchers because the underlying GetEnvironment
routine has no parameters. GetEnvironment
is a function that simply returns an alpha
value, which means this dispatcher class must
- declare a variable to store the return value from the function.
- call the function and assign the return value to the variable.
- serialize the return value into the JSON-RPC response to the caller.
Notice that the data division of the DispatchInternal
method has a new string
variable named returnValue
:
returnValue, string
This method also includes a call to the Synergy function:
returnValue = %GetEnvironment
And there is code to serialize the outbound return value:
;;Function return value
serializer.ArgumentData(0,%atrim(returnValue),FieldDataType.StringField,,0,false)
This code essentially adds the return value to the JSON-RPC response that will be returned to the caller. The parameters for ArgumentData
are the following:
- The argument number, 0, representing the return value of the function
- The actual value to be returned
- The data type of the argument, using the ENUM FieldDataType
- The length of the data being returned
- The number of decimal places (for implied decimal fields)
- A Boolean value indicating whether the value contains any binary data
In this case, the routine being called has one inbound parameter and is a function that returns an alpha
value. This means this dispatcher class must
- declare variables for the logical name (to pass to the function) and for the function's return value.
- call the function, passing the parameter variable and assigning the return value to the return value variable.
- serialize the return value into the JSON-RPC response to the caller.
Notice that in the data division of the DispatchInternal
method, there is a string
variable (arg1
) for the logical name and a string
variable named returnValue
:
;;Argument 1 (REQUIRED IN aLogicalName string)
arg1, string
returnValue, STRING
The method also has code to extract the value of the inbound parameter from the received JSON-RPC message and store the value in arg1
:
;;Argument 1 (REQUIRED IN aLogicalName string)
arg1 = dispatcher.GetText(arguments[1])
There is also code to call to the Synergy function:
returnValue = %GetLogicalName(arg1)
And there is code to serialize any outbound return value and/or parameters:
;;Function return value
serializer.ArgumentData(0,%atrim(returnValue),FieldDataType.StringField,,0,false)
The traditional Synergy AddTwoNumbers
routine has three parameters, all defined as numeric
. There are two in
parameters and one out
parameter. This means this dispatcher class must
- declare variables for the three parameter values.
- extract the values of the inbound parameters from the received JSON-RPC message.
- call the subroutine.
- serialize the
out
parameter into the JSON-RPC response to the caller.
In the data division of the DispatchInternal
method, there are three decimal
variables (arg1
, arg2
and arg3
):
record
requestId, int
arguments, JSON_ELEMENT
argumentDefinition, @ArgumentDataDefinition
;;Argument 1 (REQUIRED IN number1 d28.10)
arg1, d28.10
;;Argument 2 (REQUIRED IN number2 d28.2)
arg2, d28.2
;;Argument 3 (REQUIRED OUT result d28.10)
arg3, d28.10
endrecord
The method has code to extract the values of the inbound parameters from the received JSON-RPC message and store the values in the arg1
and arg2
variables:
;;------------------------------------------------------------
;;Prepare variables for arguments
arguments = callFrame.GetProperty("params")
;;Argument 1 (REQUIRED IN number1 d28.10)
arg1 = dispatcher.GetImplied(arguments[1])
;;Argument 2 (REQUIRED IN number2 d28.2)
arg2 = dispatcher.GetImplied(arguments[2])
;;Argument 3 (REQUIRED OUT result d28.10)
Also notice that the arguments
variable is used to represent the arguments that are passed to the routine and is populated by the code arguments = callFrame.GetProperty("params")
. You can use one of several helper methods that are provided by the RoutineDispatcher
class (represented here by the dispatcher
variable) to access the data associated with each parameter. (TODO: Document all the helper methods and provide example code here.)
There is also code to call to the underlying subroutine:
;;------------------------------------------------------------
;; Call the underlying routine
xcall AddTwoNumbers(arg1,arg2,arg3)
And there is code to serialize the outbound return value:
;;--------------------------------------------------------------------------------
;;Argument 3 (REQUIRED OUT result d28.10)
serializer.ArgumentData(3,arg3,FieldDataType.ImpliedDecimalField,28,10,false)
Next topic: Adding the Main Dispatcher Class
-
Tutorial 2: Building a Service from Scratch
- Creating a Basic Solution
- Enabling OData Support
- Configuring Self Hosting
- Entity Collection Endpoints
- API Documentation
- Single Entity Endpoints
- OData Query Support
- Alternate Key Endpoints
- Expanding Relations
- Postman Tests
- Supporting CRUD Operations
- Adding a Primary Key Factory
- Adding Create Endpoints
- Adding Upsert Endpoints
- Adding Patch Endpoints
- Adding Delete Endpoints
-
Harmony Core Code Generator
-
OData Aware Tools
-
Advanced Topics
- CLI Tool Customization
- Adapters
- API Versioning
- Authentication
- Authorization
- Collection Counts
- Customization File
- Custom Field Types
- Custom File Specs
- Custom Properties
- Customizing Generated Code
- Deploying to Linux
- Dynamic Call Protocol
- Environment Variables
- Field Security
- File I/O
- Improving AppSettings Processing
- Logging
- Optimistic Concurrency
- Multi-Tenancy
- Publishing in IIS
- Repeatable Unit Tests
- Stored Procedure Routing
- Suppressing OData Metadata
- Traditional Bridge
- Unit Testing
- EF Core Optimization
- Updating a Harmony Core Solution
- Updating to 3.1.90
- Creating a new Release
-
Background Information