Commands and Operations

When writing custom components you may want to take advantage of Geocortex Mobile's large built-in suite of command and operations or your own custom commands and operations.

Running Commands and Operations#

Services and components can run commands and operations through dependency injection.

class CustomComponent : ComponentBase
{
private readonly SystemOperations _systemOperations;
public CustomComponent(SystemOperations systemOperations)
{
_systemOperations = systemOperations;
}
public async void CopyButtonClicked(string text)
{
await _systemOperations.CopyToClipboard.ExecuteAsync(text);
}
...
}

Implementing Commands and Operations#

Services and components can also register an implementation for any command or operation. Commands and operations can either be registered and implemented directly in a service or component, or registered in a class that extends OperationsBase for ease of use by other components and services.

note

Multiple implementations can be registered for a Command or Operation.

Direct Registration and Implementation#

Commands and operations can be directly registered and implemented in a service or component through the IOperationRegistry. This pattern can be useful for registering dynamically generated commands or implementations.

important

It is vital that subscription handles are cleaned up when the object is cleaned up, otherwise dangling references can occur. This can be done by implementing the IDisposable and IDisposableTracker interface, and then providing this as the second argument to a call to subscribe. ServiceBase and ComponentBase already implement these interfaces so you don't have to.

class CustomService : ServiceBase
{
private readonly IOperationRegistry _operationRegistry;
public CustomService(IOperationRegistry operationRegistry)
{
// Define an operation that takes a string and returns the length of it.
operationRegistry.Operation<string, int>("custom.string-len").RegisterExecute(_executeStringLen, this);
}
private async Task<int> _executeStringLen(string arg)
{
return arg != null ? arg.Length : 0;
}
...
}

Registration with OperationsBase#

Commands and operations can also be defined in an OperationsBase class, which can then be injected into any service or component that wants to register an implementation.

  • An IVoidOperation produces no output, and optionally takes an input.
public IVoidOperation NoInputNoOutput => GetVoidOperation("fire.phasers");
public IVoidOperation<Temperature> SomeInputNoOutput => GetVoidOperation<Temperature>("tea.earl-grey");
  • An IOperation produces an output, and optionally takes an input.
public IOperation<SomeOutput> NoInputSomeOutput => GetOperation<SomeOutput>("custom.operation");
public IOperation<Deuterium, WarpSpeed> SomeInputSomeOutput => GetOperation<Deuterium, WarpSpeed>("warp-drive.engage");
note

Operation names in Geocortex Mobile generally take the format <category>.<name>, with multiple words kebab-cased.

These types can be used to define a set of operations in an OperationsBase class that is registered with Autofac. Implementations for the operations can then be registered in a service or component.

[assembly: Export(typeof(CustomOperations), SingleInstance = true)]
namespace App1.Operations
{
class CustomOperations : OperationsBase
{
public IVoidOperation<string> RunCustomCommand => GetVoidOperation<string>("custom.command-string-input");
public IOperation<int> RunCustomOperation => GetOperation<int>("custom.operation-int-output");
public IOperation<string, int> RunCustomOperationWithInput => GetOperation<string, int>("custom.operation-string-input-int-output");
public Operation(IOperationRegistry operationRegistry)
: base(operationRegistry)
{
}
}
}

Running Custom Commands#

You can run the custom commands or operations you define by either injecting the appropriate OperationsBase class or using the IOperationRegistry to run the command or operation by name.

class CustomService : ServiceBase
{
private readonly CustomOperations _customOperations;
private readonly IOperationRegistry _operationRegistry;
public CustomService(CustomOperations customOperations, IOperationRegistry operationRegistry)
{
_customOperations = customOperations;
_operationRegistry = operationRegistry;
}
private async void runSomeCommand()
{
await _customOperations.RunCustomCommand.ExecuteAsync("some arg");
// Execute the same operation but by name instead of through the `OperationsBase` container.
await _operationRegistry.VoidOperation("custom.command-string-input").ExecuteAsync("Some arg");
}
...
}

Relevant SDK Sample#

The Geocortex Mobile SDK Samples project has a sample of implementing a command with a custom service.