Skip to content

plugin sdk lifecycle

Andre Lafleur edited this page Jan 16, 2026 · 1 revision

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. Do not override this method.

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.

Related Guides

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

Clone this wiki locally