Repository navigation
Plugin Development
Simulcast Utility plugins are .NET class libraries containing one public, non-abstract implementation of ISimulcastPlugin. Plugins can observe and control receivers, persist isolated data, expose settings, add themed WPF interface elements, show notifications and dialogs, apply complete application themes, dispatch navigation commands, and log through the host.
The plugin API is still pre-release. Build against the contract assemblies shipped with the exact application version you target.
Assembly discovered
|
InitializeAsync (once per loaded plugin instance)
|
EnableAsync
|
HandleApplicationArgumentsAsync
|
DisableAsync
|
Dispose / unload load context
Store the supplied IPluginContext, construct plugin services, and load lightweight state. Do not attach UI, timers, or event handlers here unless they are safe while the plugin is disabled. Initialization can happen again after a plugin-directory or plugin-data-directory reload because a new plugin instance is created.
Attach event handlers, create timers, apply theme resources, and insert UI. Treat this method as repeatable across disable/enable cycles. Guard against duplicate subscriptions.
Reverse every action from EnableAsync: unsubscribe events, stop and dispose timers, cancel background work, release media objects, remove themes, and clear references to injected controls. Registered UI cleanup actions and plugin dialogs are also removed by the host, but the plugin remains responsible for its own references.
Inspect startup arguments intended for the plugin. Ignore arguments you do not own. Avoid blocking startup; offload long work and honor cancellation.
| Member | Use |
|---|---|
InstallationDirectory |
Folder containing the plugin assembly and private assets |
ReceiverRepository |
Low-level loading and saving of the full receiver collection |
ReceiverManager |
Source of truth for configured and selected receivers |
ReceiverCommandManager |
Discovery, refresh, status, and receiver command execution |
ApplicationDispatcher |
Request supported navigation/actions from the main shell |
ThemeManager |
Apply/remove a resource dictionary and select light/dark title-bar mode |
UiManager |
Locate named elements, work on the UI thread, add cleanup, show notifications/dialogs |
DataStore |
Plugin-isolated persistent JSON data |
Logger |
Host-created ILogger writing into the application log |
See Plugin API Reference for signatures and Receiver APIs for receiver examples.
The logger category is Plugin.<plugin name>. Messages follow the application's configured minimum level and are written to the same session log.
using Microsoft.Extensions.Logging;
public Task EnableAsync(CancellationToken cancellationToken = default)
{
_context!.Logger.LogInformation("Enabling schedule integration {Version}.", Info.Version);
return Task.CompletedTask;
}
private async Task RefreshScheduleAsync(CancellationToken cancellationToken)
{
try
{
_context!.Logger.LogDebug("Refreshing the schedule.");
await LoadScheduleAsync(cancellationToken);
}
catch (Exception ex)
{
_context!.Logger.LogError(ex, "Schedule refresh failed.");
throw;
}
}Use structured message templates instead of string interpolation so fields remain searchable. Do not log receiver credentials, private identifiers, access tokens, or complete command payloads containing sensitive values.
- Unsubscribe every event with the same delegate instance used to subscribe.
- Cancel and dispose
CancellationTokenSourceinstances. - Stop and dispose timers, media players, sockets, watchers, and HTTP responses.
- Remove plugin resource dictionaries or allow host cleanup to do so.
- Register removal actions for every injected control.
- Close plugin-owned windows and dialogs.
- Clear static references to plugin types and WPF elements.
- Avoid background tasks that outlive
DisableAsync.