Added the ability for plugins to interact

Tags:

Starting from version 6.2, a plugin that implements a certain function can register it in the API as an external operation so that other plugins can invoke this function.

The developer of the plugin that will act as the server must declare the name of the external service, the names of the operations of this service, and the data structures used. When starting the server plugin, each operation must be registered using the RegisterExternalOperation method.

In the plugin that will act as the client, the external operation can be invoked using CallExternalOperation by specifying the service name and operation name previously obtained from the server plugin developer. The external operation receives a request as input, and a response will be received as output, where the structure of the request and response is also declared in advance by the server plugin developer.

Since the order of plugin startup is nondeterministic, it is possible that the client plugin is already running while the server plugin is not yet started, and therefore, the external operations implemented in it are not yet registered in the API. You can monitor the registration/removal of external operations by subscribing to PluginContext.Notifications.ExternalOperationChanged. Additionally, you can request the list of available services and their operations at any time through PluginContext.Operations.GetExternalOperations.

The role of the API when invoking external operations is limited to passing the request from the client plugin to the server plugin and passing the response back after the operation is completed. Plugin developers must agree on how errors will be encoded in the transmitted data, how to ensure versioning, and so on. In the basic version, the request and response are transmitted as byte arrays, which the interacting parties interpret in a previously agreed manner. To relieve developers from the need to serialize and deserialize data in simple cases, helper methods RegisterExternalOperation<TRequest, TResponse> and CallExternalOperation<TRequest, TResponse> have been added to OperationServiceExtensions, allowing arbitrary serializable types to be passed as requests and responses (TRequest and TResponse). In a trivial case, when a single value of a public type needs to be transmitted, you can directly specify, for example, int or string. If multiple values need to be transmitted, tuples (value tuples) can be used. To transmit complex objects, the server plugin developer can create a separate library with a set of DTO classes marked with the Serializable attribute, use this library in the server plugin, and also publish it for client plugin developers. Examples of usage can be found in the ExternalOperationsTester class of the Resto.Front.Api.SamplePlugin from the SDK.

Currently, the new functionality is only available in API V6, but with the release of new versions (V7+), it is expected that plugins operating on one version of the API will be able to invoke functions of plugins operating on another version of the API. Interaction is only available within a single instance of the SyrveFront application, meaning that a plugin running on one computer cannot access a plugin running on another computer via the API.