Service Reference
Services act as a repository of accessible behavior and data, and can be used for a variety of purposes, from implementing commands and operations, to managing shared data, to interfacing with the REST API of an external service.
Service Registration
All services need to be registered with VertiGIS Studio Mobile. A service is created by extending the ServiceBase
class and registering the service class with Autofac through an assembly attribute.
VertiGIS Studio Mobile uses Autofac to register, locate, and inject components, services and other classes. See dependency injection for more info.
[assembly: Service(typeof(CustomService), PropertiesAutowired = true)]
namespace App1.Services
{
class CustomService : ServiceBase
{
...
}
}
Service Lifecycle
On application load, all services that have been registered with wih VertiGIS Studio Mobile are first created and then initialized.
Services are destroyed (i.e. the _onDestroy
method is invoked) when the application is destroyed, e.g. when killing the application or switching applications in VertiGIS Studio Go.
Initialization and Teardown
Services have an initialization method, which can be used to perform asynchronous startup logic, and a teardown method, which can be used to free resources when the application is destroyed.
Always call base.Dispose(disposing)
when overriding the Dispose
method. ServiceBase
already implements IDisposable
and IDisposableTracker
, so only override the Dispose
method if you have created new managed resources which need to be cleaned up.
To learn more about memory management in VertiGIS Studio Mobile, check out this article, and the relevant SDK sample.
[assembly: Service(typeof(CustomService), PropertiesAutowired = true)]
namespace App1.Services
{
class CustomService : ServiceBase
{
private bool disposed = false;
public CustomService()
: base()
{
// On creation logic here
}
protected override async Task DoInitialize()
{
// Async on initialization logic here
return;
}
protected override void Dispose(bool disposing)
{
if (disposed)
{
return;
}
if (disposing)
{
// Clean up managed resources.
// ...
}
// Clean up unmanaged resources.
// ...
base.Dispose(disposing);
disposed = true;
}
}
}
Dependency Injection
Services interact with the larger application by injecting their dependencies. Services can inject commands and operations, other services, and any other class registered with Autofac.
The following example injects the UI operations and the dialog controller into a custom service.
Services are not intended to directly interact with each other. Instead, services should implement operations which can be called by other services to indirectly interact.
[assembly: Service(typeof(CustomService), PropertiesAutowired = true)]
namespace App1.Services
{
class CustomService : ServiceBase
{
private UIOperations _uiOperations;
private IDialogController _dialogController;
public CustomService(UIOperations uiOperations, IDialogController dialogController)
: base()
{
_uiOperations = uiOperations;
_dialogController = dialogController;
}
...
}
}
Configuration Models
Like components, services can be configured through the app config. Services can participate in the app config by creating and injecting the appropriate item type.
Each item type in the application is bound to a class registered as an AppItem
with autofac. This class instantiates itself with values from the app config in its constructor, acting as a configuration model.
A service can consume configuration by injecting the AppItem
class as a dependency in its constructor.
- Service Configuration Model
- Service
- App Config
[assembly: Service(typeof(CustomService), PropertiesAutowired = true)]
namespace App1.Services
{
class CustomService : ServiceBase
{
private IAppItem<CustomServiceSettings> _appItem;
public CustomService(IAppItem<CustomServiceSettings> appItem)
: base()
{
_appItem = appItem;
}
protected override async Task DoInitialize()
{
var settings = await _appItem.ResolveAsync();
if (settings == null)
{
return;
}
Logger.Debug($"Value of setting is '{settings.SomeSetting}'");
}
}
}
[assembly: AppItem(CustomServiceSettings.AppItemType, typeof(CustomServiceSettings))]
namespace App1.Services
{
[ServiceAppItem(AppItemType)]
public class CustomServiceSettings
{
public const string AppItemType = "custom-service";
public string SomeSetting { get; set; }
public CustomServiceSettings()
{
}
public CustomServiceSettings(Properties properties)
{
if (properties is null)
{
throw new System.ArgumentNullException(nameof(properties));
}
if (properties.TryGetValue("someSetting", out string someSetting))
{
SomeSetting = someSetting;
}
}
}
}
{
"schemaVersion": "1.0",
"items": [
...{
"$type": "custom-service",
"id": "custom-service",
"someSetting": "Some Value"
}
]
}
Relevant SDK Samples
Check out the relevant VertiGIS Studio Mobile SDK Samples:
Next Steps
Learn how to use Commands and Operations with Services
Learn how to run and implement commands and operations with custom services
Learn about Service Interactions
Learn about how services and components can interact
Build a Custom Command with a Custom Service
Follow a step by step guide to building a custom command with a custom service
Build a Service that Manages Dynamic Data
Built a service that manages a dynamic data source and exposes it to components