Skip to content

plugin sdk lifecycle

Andre Lafleur edited this page Feb 3, 2026 · 3 revisions

About plugin lifecycle

Understanding the plugin lifecycle is crucial for proper initialization, operation, and cleanup.

Lifecycle Overview

flowchart TB
    Start[Plugin starts] --> Constructor
    subgraph Phase1[" "]
        Constructor["1. Constructor called<br/>Engine, Logger, Culture are NULL<br/>PluginGuid is Guid.Empty"]
    end

    Constructor --> Initialize
    subgraph Phase2[" "]
        Initialize["2. Initialize(engine, roleGuid, culture) called<br/>Engine, PluginGuid, Logger, Culture populated<br/>Report filters set and handlers registered"]
    end

    Initialize --> Loaded
    subgraph Phase3[" "]
        Loaded["3. OnPluginLoaded() called<br/>Called by Initialize()"]
    end

    Loaded --> Database
    subgraph Phase4[" "]
        Database["4. Database layer initialized (if IPluginDatabaseSupport)<br/>SetDatabaseInformation and start state machine"]
    end

    Database --> Started
    subgraph Phase5[" "]
        Started["5. OnPluginStart() called<br/>Database state may still be connecting"]
    end

    Started --> Running
    subgraph Phase6[" "]
        Running["6. Plugin runs<br/>Process queries, handle events/actions<br/>Update entity states"]
    end

    Running --> Shutdown[7. Plugin shutdown initiated]
    Shutdown --> Dispose

    subgraph Phase7[" "]
        Dispose["8. Dispose() called<br/>Unsubscribe events, stop workers<br/>Dispose resources"]
    end

    Dispose --> Destroyed[9. Plugin instance destroyed]
Loading

Lifecycle Methods

Method When called Purpose
Constructor Plugin instantiation Initialize member variables only
Initialize() Called by the plugin host Set base properties and run OnPluginLoaded()
OnPluginLoaded() End of Initialize() Register handlers, filters, and services
OnPluginStart() After database layer starts (if supported) Start background work and runtime processing
Dispose() Plugin shutdown Clean up resources and unsubscribe events

Constructor

What's available:

  • Engine - null
  • Logger - null
  • PluginGuid - Guid.Empty
  • Culture - null

Initialize member variables only.

public MyPlugin()
{
    m_httpClient = new HttpClient();
    m_cancellation = new CancellationTokenSource();
}

Do not access Engine, Logger, or PluginGuid in the constructor.

Initialize()

Called by the plugin host.

What happens:

  • Engine, PluginGuid, Logger, and Culture are set
  • Report filters are applied from SupportedQueries and SupportedCustomReports
  • Query and entity event handlers are registered
  • OnPluginLoaded() is called

This work is handled by the base Plugin class.

OnPluginLoaded()

First lifecycle method where you can use the Engine.

What's available:

  • Engine - fully initialized
  • Logger - ready to use
  • PluginGuid - your role GUID
  • Culture - current culture
  • Database - may not be ready (if using database support)

What to do:

protected override void OnPluginLoaded()
{
    // Set up event filters
    Engine.SetEventFilter(new List<EventType> 
    { 
        EventType.AccessGranted,
        EventType.DoorOpenedTooLong 
    });

    // Subscribe to events
    Engine.EventReceived += OnEventReceived;
    Engine.ActionReceived += OnActionReceived;
    Engine.EntitiesInvalidated += OnEntitiesInvalidated;

    // Register request handlers using Plugin's protected helper methods
    AddRequestHandler<MyRequest, MyResponse>(HandleRequest);

    // Initialize services (but don't start long-running work yet)
    InitializeExternalConnection();

    // Report initial state
    ModifyPluginState(new PluginStateEntry("Startup", "Plugin loaded"));
}

What not to do:

  • Do not start background workers yet
  • Do not access the database yet (if using database support)
  • Do not perform long-running initialization

OnPluginStart()

Called after the database layer starts (if supported). The database state can still be connecting.

What's available:

  • Engine - fully initialized
  • Database state - may still be connecting (if using database support)

What to do:

protected override void OnPluginStart()
{
    // Start background workers
    m_backgroundWorker = Task.Run(() => BackgroundWork(m_cancellation.Token));

    // Begin data processing
    StartDataProcessing();

    // Report ready state
    ModifyPluginState(new PluginStateEntry("Running", "Plugin started"));
}

This is the right place to:

  • Start background workers
  • Begin periodic tasks
  • Start data processing
  • Perform initialization that does not require a connected database

For database-dependent work, wait for DatabaseState.Connected in OnDatabaseStateChanged().

Dispose()

Called when the plugin is shutting down.

What to do:

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        // Unsubscribe from all events
        Engine.EventReceived -= OnEventReceived;
        Engine.ActionReceived -= OnActionReceived;
        Engine.EntitiesInvalidated -= OnEntitiesInvalidated;

        // Stop background workers
        m_cancellation?.Cancel();

        // Remove request handlers
        RemoveRequestHandler<MyRequest, MyResponse>(HandleRequest);

        // Dispose managed resources
        m_httpClient?.Dispose();
        m_databaseConnection?.Dispose();
    }
}

Critical rules:

  • Unsubscribe from events
  • Stop background workers
  • Dispose managed resources
  • Handle partially initialized state

Database Lifecycle Integration

When a plugin implements IPluginDatabaseSupport, initialization happens in this order:

  1. Constructor
  2. Initialize() - base initialization and OnPluginLoaded() runs
  3. DatabaseManager.SetDatabaseInformation() - connection info provided
  4. Database layer created - reads GetDatabaseUpgradeItems()
  5. Database state machine starts
  6. Creating state calls GetSpecificCreationScript() when database is missing
  7. Upgrading state runs upgrade items when version is behind
  8. OnDatabaseStateChanged() notifications for database state changes
  9. OnPluginStart() is called

This means:

  • In OnPluginLoaded(), database may not be ready
  • OnPluginStart() does not guarantee DatabaseState.Connected
  • Use OnDatabaseStateChanged() to wait for DatabaseState.Connected

See Plugin SDK Database for details.

Threading Considerations

Lifecycle methods are called by the plugin host. Callbacks from timers and task continuations run on background threads.

Key points:

  • Use Engine.QueueUpdate() or Engine.QueueUpdateAndWait() to update entities from background work

Example: queue an entity update from a timer callback.

private void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
    Engine.QueueUpdate(() =>
    {
        var entity = Engine.GetEntity<CustomEntity>(m_entityGuid);
        entity.RunningState = State.Running;
    });
}

See Plugin SDK Threading for detailed threading patterns, QueueUpdate usage, async/await considerations, and background worker examples.

See also

Security Center SDK

  • 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

    • Workspace SDK

    • 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.

Web SDK Developer Guide

  • 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.
  • 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 Developer Guide


Web Player Developer Guide

  • 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.

Clone this wiki locally