Lifecycle of a custom operator
Whenever a custom operator is used, an instance of the associated C# class is created, and GQI will call the relevant lifecycle methods that define its behavior.
The simplified diagram below shows in what order each GQI lifecycle method is called.
Note
In practice, the lifecycle methods that will be called depend on various conditions. Refer to the detailed lifecycle overview for a complete overview.

When is a custom operator instance created?
A new custom operator instance is created every time one of the following requests occur:
- A capability request, used to determine the query arguments used in the query builder.
- A columns request, used to determine which columns are available without fetching any data.
- A new session request, used to fetch and transform data.
The type of request also determines which lifecycle methods are used.
Detailed lifecycle overview
The following lifecycle methods exist for custom operators:
| Method | Interface | Required | Availability |
|---|---|---|---|
| Constructor | None | No | Always |
| OnInit | IGQIOnInit | No | From DataMiner 10.4.5/10.5.0 onwards |
| GetInputArguments | IGQIInputArguments | No | Always |
| OnArgumentsProcessed | IGQIInputArguments | No | Always |
| HandleColumns | IGQIColumnOperator | No | Always |
| Optimize | IGQIOptimizableOperator | No | Always |
| HandleRow | IGQIRowOperator | No | Always |
| OnDestroy | IGQIOnDestroy | No | From DataMiner 10.4.5/10.5.0 onwards |
| Dispose | IDisposable | No | From DataMiner 10.5.0 [CU18]/10.6.0 [CU6]/10.6.9 onwards when using the GQI DxM. |
The lifecycle methods that are called on a custom operator instance depend on the following conditions:
- The interfaces that are implemented by the associated C# class.
- The type of GQI request for which the instance was created.
- The operators used in the query.
- The result of previous lifecycle methods.
The following diagram shows a complete overview of all possible lifecycle paths.

Constructor
When a new custom operator instance is created, GQI first calls a constructor. Before DataMiner 10.5.0 [CU18]/10.6.0 [CU6]/10.6.9, this is always the public parameterless constructor. If the class does not explicitly declare a constructor, the default constructor is used.
From DataMiner 10.5.0 [CU18]/10.6.0 [CU6]/10.6.9 onwards, custom operators using the Skyline.DataMiner.Core.GQI.Extensions API and the GQI DxM can use constructor injection. GQI still uses the public parameterless constructor when one exists. Otherwise, it resolves the constructor parameters before OnInit. If construction fails, no other lifecycle methods are called for that instance.
OnInit
Building block interface: IGQIOnInit
If implemented, OnInit is always the first lifecycle method. It can provide references to dependencies like a logger or an SLNet connection and can be used to initialize resources that should be available during the lifetime of the custom operator instance.
Important
Resources that are successfully initialized here should be cleaned up in the OnDestroy lifecycle method. For cleanup that must also happen when OnInit fails, implement IDisposable.
Note
When resources are only required to determine the columns, the initialization should instead be done in the HandleColumns lifecycle method to avoid unnecessary resource allocations.
GetInputArguments
Building block interface: IGQIInputArguments
If implemented, the GetInputArguments method defines the arguments that can be used to configure the custom operator in a query.
Later, the arguments defined here will determine which argument values are available in the OnArgumentsProcessed lifecycle method.
OnArgumentsProcessed
Building block interface: IGQIInputArguments
If implemented, the OnArgumentsProcessed method gives access to the values of the arguments defined in the GetInputArguments lifecycle method that were specified in the query.
HandleColumns
Building block interface: IGQIColumnOperator
If implemented, the HandleColumns lifecycle method allows you to transform the query columns by:
- Adding new columns
- Renaming existing columns
- Removing existing columns
This method can also be used to just provide access to the currently available columns.
Important
Avoid the implicit use of query columns in your custom operator by retrieving them explicitly via query arguments. This both informs users which columns are relevant and prevents unintended side effects when the query is optimized.
Optimize
Building block interface: IGQIOptimizableOperator
If implemented, the Optimize lifecycle method allows the custom operator to interpret downstream operators that are applied directly and makes it possible to adjust its behavior to improve query execution performance.
This lifecycle method may be called multiple times for the same instance when the custom operator removes or reorders other operators.
HandleRow
Building block interface: IGQIRowOperator
If implemented, the HandleRow lifecycle method defines how query rows will be transformed. It will be called exactly once for each row in the current query result, and for every row you can do any of the following:
- Get the row key
- Get or set the row metadata
- Get or set cell values and display values
- Remove the row from the query result
Note
If the custom operator removed a column in the HandleColumns lifecycle method, you can still access the associated cell value here.
OnDestroy
Building block interface: IGQIOnDestroy
If implemented, OnDestroy is called during cleanup when OnInit completed successfully. It allows you to clean up resources that were used during the lifetime of the custom operator instance.
Important
The OnDestroy lifecycle method will not be called when the OnInit lifecycle method failed. For cleanup that must happen regardless of the OnInit result, use Dispose.
Dispose
Building block interface: IDisposable
From DataMiner 10.5.0 [CU18]/10.6.0 [CU6]/10.6.9 onwards, when a custom operator using the Skyline.DataMiner.Core.GQI.Extensions API and the GQI DxM implements IDisposable, GQI calls Dispose when the instance is cleaned up. Use this to release resources that are tied to the instance lifetime.