-
Notifications
You must be signed in to change notification settings - Fork 4
workspace sdk modules
A workspace module is the entry point for extending Security Desk or Config Tool. Modules are discovered and loaded by the host application, and they register extensions such as tasks, pages, components, and services.
Create a workspace module by inheriting from Genetec.Sdk.Workspace.Modules.Module and overriding the Load and Unload methods:
public class SampleModule : Module
{
public override void Load()
{
// Register extensions here
}
public override void Unload()
{
// Clean up resources here
}
}Your module class must meet these requirements:
-
Public class: The module class must be declared
public. - Parameterless constructor: Security Center uses reflection to instantiate modules and requires a constructor that takes no parameters. If you do not define any constructor, the implicit default constructor satisfies this requirement.
-
Multiple modules per assembly: A single assembly can contain multiple module classes. Security Center discovers and loads all public classes that inherit from
Module.
| Member | Type | Description |
|---|---|---|
Workspace |
Workspace | The workspace instance (available after Initialize) |
UniqueId |
Guid (virtual) | Module's unique identifier (defaults to Type.GUID) |
Load() |
abstract void | Called when module loads; register extensions here |
Unload() |
abstract void | Called when module unloads; clean up here |
Initialize(Workspace) |
void | Called by framework to provide Workspace instance |
Modules progress through four stages:
- Constructor: Security Center instantiates your module using reflection
-
Initialize: The framework calls
Initialize(Workspace)to provide the workspace instance -
Load: The framework calls
Load()where you register all extensions -
Unload: The framework calls
Unload()during application shutdown
The Workspace property is not available in the constructor. Access it only in Load, Unload, or after Initialize completes.
Modules are loaded in the order they are discovered from the plugin configuration. There is no guaranteed loading order between modules, and no priority mechanism exists. Do not depend on another module being loaded before yours.
If your module throws an exception during Load(), Security Center logs the error and continues loading other modules. Your module will not be added to the workspace, but other modules remain unaffected. The same applies to Unload(): exceptions are caught and logged, allowing other modules to unload normally.
The Load() method is called before the application connects to the Directory server. Do not assume the client is connected when Load() executes. Tasks and pages can work offline by default through the AllowOfflineExecution property on PageDescriptor.
If your module needs to perform actions after connection is established, subscribe to the LoggedOn event:
public override void Load()
{
Workspace.Sdk.LoginManager.LoggedOn += OnLoggedOn;
// Register extensions that work offline
}
private void OnLoggedOn(object sender, LoggedOnEventArgs e)
{
// Perform actions that require connection
}Access the Platform SDK Engine through Workspace.Sdk:
public override void Load()
{
var engine = Workspace.Sdk;
// Subscribe to events (works before connection)
engine.EventReceived += OnEventReceived;
// Check connection before accessing connected-only properties
if (engine.LoginManager.IsConnected)
{
var user = engine.LoggedUser;
}
}All modules share the same Engine instance with the host application. See Platform SDK Overview for Engine operations.
Modules can interact with each other through shared workspace resources:
-
Services: Register a service in one module and retrieve it in another using
Workspace.Services.Get<T>(). Services must implement an interface that extendsIService. -
Components: Access components registered by other modules through
Workspace.Components. -
Modules: Enumerate loaded modules through
Workspace.Modules, though direct module-to-module dependencies are discouraged.
// Define a service interface that extends IService
public interface IMyCustomService : IService
{
void DoSomething();
}
// Implement the service
public class MyCustomService : IMyCustomService
{
public void Initialize(Workspace workspace) { }
public void DoSomething() { /* ... */ }
}
// Module A: Register the service
public override void Load()
{
var myService = new MyCustomService();
myService.Initialize(Workspace);
Workspace.Services.Register(myService);
}
// Module B: Retrieve the service
public override void Load()
{
var service = Workspace.Services.Get<IMyCustomService>();
if (service != null)
{
service.DoSomething();
}
}Since loading order is not guaranteed, check for null when retrieving services from other modules. Consider subscribing to Workspace.Initialized to access services after all modules have loaded.
Register extensions in the Load method using the appropriate workspace collection:
public override void Load()
{
// Register a task
var task = new MyTask();
task.Initialize(Workspace);
Workspace.Tasks.Register(task);
// Register a component
var widget = new MyWidgetBuilder();
widget.Initialize(Workspace);
Workspace.Components.Register(widget);
// Register an options extension
var options = new MyOptionsExtension();
options.Initialize(Workspace);
Workspace.Options.Register(options);
}| Extension type | Registration target | Method |
|---|---|---|
| Task | Workspace.Tasks |
Register(Task) |
| Component | Workspace.Components |
Register(Component) |
| OptionsExtension | Workspace.Options |
Register(OptionsExtension) |
| IService | Workspace.Services |
Register(IService) |
| ContextualAction | IContextualActionsService |
Register(ContextualAction) |
| EventExtender | IEventService |
RegisterEventExtender(EventExtender) |
| ConfigPage | IConfigurationService |
Register(...) |
Check Workspace.ApplicationType to register extensions only for the appropriate application:
public override void Load()
{
switch (Workspace.ApplicationType)
{
case ApplicationType.SecurityDesk:
RegisterSecurityDeskComponents();
break;
case ApplicationType.ConfigTool:
RegisterConfigToolComponents();
break;
}
}If your module uses third-party libraries beyond the Genetec SDK, you must configure assembly resolution. The SDK assemblies are automatically resolved by Security Center.
This approach configures Security Center to automatically probe your module's directory for dependencies. Set it in the registration XML:
<PluginInstallation>
<Version>1</Version>
<Configuration>
<Item Key="Enabled" Value="True" />
<Item Key="ClientModule" Value="C:\MyModule\MyModule.dll" />
<Item Key="AddFoldersToAssemblyProbe" Value="True" />
</Configuration>
</PluginInstallation>Place all third-party DLLs in the same directory as your module DLL.
For custom loading logic, use the AssemblyResolver class in a static constructor:
public class SampleModule : Module
{
static SampleModule() => AssemblyResolver.Initialize();
public override void Load() { /* ... */ }
public override void Unload() { }
}The static constructor runs before any instance is created, ensuring dependencies resolve correctly.
Use AddFoldersToAssemblyProbe for most scenarios. It requires no code and handles simple dependencies automatically. Use AssemblyResolver when you need custom loading logic, dependencies in multiple locations, or version-specific behavior.
For module registration during development and production deployment, see Deploying plugins and workspace modules.
Release resources in the Unload method:
public override void Unload()
{
// Unsubscribe from events
Workspace.Sdk.EventReceived -= OnEventReceived;
// Dispose loggers
_logger?.Dispose();
// Release other resources
}The Unload() method is called when the workspace is disposed during normal application shutdown. Modules are unloaded in reverse order of loading. However, Unload() may not be called if the application crashes, is forcefully terminated, or exits abnormally. Design for graceful degradation if cleanup does not occur.
-
Security Center SDK Developer Guide Overview of the SDK framework and how to build integrations with Security Center.
-
Platform SDK
- Overview Introduction to the Platform SDK and core concepts.
- Connecting to Security Center Step-by-step guide for connecting and authenticating with the SDK.
- SDK Certificates Details certificates, licensing, and connection validation.
- Referencing SDK Assemblies Best practices for referencing assemblies and resolving them at runtime.
- SDK Compatibility Guide Understanding backward compatibility and versioning in the SDK.
- Entity Guide Explains the core entity model, inheritance, and how to work with entities.
- Entity Cache Guide Describes the engine's local entity cache and synchronization.
- Transactions Covers batching operations for performance and consistency.
- Events Subscribing to real-time system events.
- Actions Sending actions to Security Center.
- Security Desk Displaying content on monitors, reading tiles, sending tasks, and messaging operators.
- Custom Events Defining, raising, and subscribing to custom events.
- ReportManager Querying entities and activity data from Security Center.
- ReportManager Query Reference Complete reference of query types, parameters, and response formats.
- Privileges Checking, querying, and setting user privileges.
- Partitions Entity organization and access control through partitions.
- Logging How to configure logging, diagnostics, and debug methods.
-
Plugin SDK
- Overview Introduction to plugin architecture and capabilities.
- Certificates SDK certificate requirements for plugin roles.
- Lifecycle Initialization and disposal patterns.
- Threading Threading model, QueueUpdate, and async patterns.
- State Management Reporting plugin health and diagnostics.
- Configuration Configuration storage and monitoring.
- Restricted Configuration Secure credential storage and admin-only configuration.
- Events Event subscription and handling.
- Queries Query processing and response handling.
- Request Manager Request/response communication with clients.
- Database Database integration and schema management.
- Entity Ownership Understanding plugin-owned entities, running state management, and ownership release.
- Entity Mappings Using EntityMappings for plugin-specific configuration and external system integration.
- Server Management High availability and server failover.
- Custom Privileges Defining and enforcing custom privileges.
- Custom Entity Types Defining and managing plugin-specific entity types.
- Resolving Non-SDK Assemblies Handling third-party dependencies in plugins and workspace modules.
- Deploying Plugins Registering and deploying plugins and workspace modules.
- .NET 8 Support Building plugins with .NET 8 and .NET Standard compatibility.
-
Workspace SDK
- Overview Introduction to client-side UI extensions for Security Desk and Config Tool.
- Certificates SDK certificate requirements for workspace modules.
- Creating Modules Module lifecycle, registration patterns, and assembly resolution.
- Tasks Executable actions, home page entries, and programmatic invocation.
- Pages Page content, lifecycle, descriptors, and navigation.
- Components Dashboard widgets, tiles, maps, credentials, and content builders.
- Tile Extensions Custom tile widgets, views, and properties panels.
- Services Built-in services for dialogs, maps, alarms, badges, and more.
- Contextual Actions Right-click context menu extensions.
- Options Extensions Custom settings pages in application preferences.
- Configuration Pages Entity configuration pages for Config Tool.
- Monitors Multi-monitor support and shared components.
- Shared Components Using monitor and workspace shared UI components.
- Commands Command execution, evaluation, and interception.
- Extending Events Adding custom fields to Security Center events.
- Map Extensions Custom map objects, layers, and providers.
- Timeline Providers Custom timeline event sources for video playback.
- Image Extractors Custom image sources for cardholder photos and custom fields.
- Credential Encoders Encoding credentials with custom encoder components.
- Cardholder Fields Extractors Importing cardholder data from external sources.
- Content Builders Building and customizing tile content in Security Desk.
-
Macro SDK
- Overview How macros work, creating and configuring macro entities, automation, and monitoring.
- Developer Guide Developing macro code with the UserMacro class and Security Center SDK.
-
- Getting Started Setup, authentication, and basic configuration for the Web SDK.
- Referencing Entities Entity discovery, search capabilities, and parameter formats.
- Entity Operations CRUD operations, multi-value fields, and method execution.
- Partitions Managing partitions, entity membership, and user access control.
- Custom Fields Creating, reading, writing, and filtering custom entity fields.
- Custom Card Formats Managing custom credential card format definitions.
- Actions Control operations for doors, cameras, macros, and notifications.
- Events and Alarms Real-time event monitoring, alarm monitoring, and custom events.
- Incidents Incident management, creation, and attachment handling.
- Reports Activity reports, entity queries, and historical data retrieval.
- Tasks Listing and executing saved report tasks.
- Macros Monitoring currently running macros.
- Custom Entity Types Listing, retrieving, and deleting custom entity type descriptors.
- System Endpoints License usage, web tokens, and exception handling.
- Performance Guide Optimization tips and best practices for efficient API usage.
- Reference Entity GUIDs, EntityType enumeration, and EventType enumeration.
- Under the Hood Technical architecture, query reflection, and SDK internals.
- Troubleshooting Common error resolution and debugging techniques.
- Media Gateway Guide Setup and configuration of the Media Gateway role for video streaming.
- Developer Guide Complete guide to integrating GWP for live and playback video streaming.
- API Reference Full API documentation with interfaces, methods, properties, and events.
- Sample Application Comprehensive demo showcasing all GWP features with timeline and PTZ controls.
- Multiplexing Sample Multi-camera grid demo using a shared WebSocket connection.