IMoBroPlugin
Each plugin must include exactly one class that implements the IMoBroPlugin interface.
This class represents the actual plugin and is instantiated by MoBro when the plugin is started.
The class must have exactly one public constructor, through which services are injected. See Using Services for details.
Lifecycle
Start
- A new instance of the plugin class is created, and all requested services are injected into its constructor.
Init()is called, followed byInitAsync(). If a plugin implements both, both are called.
Settings Change
When the user changes the plugin's settings, MoBro discards the current plugin instance and creates a new one:
- All tasks of the scheduler are removed.
Shutdown(),ShutdownAsync()and — if the plugin implementsIDisposable—Dispose()are called on the current instance.- All items registered by the plugin are removed.
- A new instance is created with the new settings, and
Init()andInitAsync()are called again.
Stop
When the plugin is stopped (e.g. disabled or uninstalled by the user, or MoBro shuts down):
- The scheduler is stopped.
Shutdown(),ShutdownAsync()andDispose()(if implemented) are called.
The plugin process is terminated if this takes longer than 5 seconds.
Error
If the constructor, Init() or InitAsync() throws an exception, the plugin is stopped and its state changes to
Error. The same happens for unhandled exceptions at runtime. See Error Handling.
- Treat the plugin instance as short-lived. Don't keep state in fields that must survive a settings change; use the persistence manager instead.
- Release resources (connections, file handles, native handles) in
Shutdown()orDispose(). Both are called whenever the plugin instance is discarded. - Scheduled tasks that are executing at the moment the plugin is shut down are not interrupted. Make sure they can cope with resources that have already been released.
Functions
The IMoBroPlugin interface defines a set of optional functions that are called by MoBro during the plugin's
lifecycle.
Implementing these functions is optional. A plugin can be created without implementing any of them.
Init()
Called once after the plugin instance has been created.
Any initialization logic, especially longer-running operations, should be placed here instead of the constructor.
Init() is the ideal place for tasks such as:
- Registering metrics
- Updating metric values
- Scheduling recurring tasks
This keeps the main business logic separate from the plugin creation (handled in the constructor).
InitAsync(): Task
The asynchronous version of Init(). Use it when initialization involves asynchronous operations.
InitAsync() is called right after Init(). If a plugin implements both, both are called.
Shutdown()
Called when the plugin instance is about to be discarded, i.e. when the plugin is stopped or its settings changed.
This is the place for cleanup actions or final tasks, such as persisting data.
ShutdownAsync(): Task
The asynchronous version of Shutdown(). Called after Shutdown().
Dispose()
Not part of IMoBroPlugin, but if the plugin class implements IDisposable, Dispose() is called after Shutdown()
and ShutdownAsync().
Example
using MoBro.Plugin.SDK;
using MoBro.Plugin.SDK.Services;
namespace Plugin.Example;
public class Plugin : IMoBroPlugin, IDisposable
{
private readonly IMoBroService _mobro;
private readonly IMoBroScheduler _scheduler;
private readonly IMoBroSettings _settings;
private readonly HttpClient _httpClient = new();
public Plugin(IMoBroService mobro, IMoBroScheduler scheduler, IMoBroSettings settings)
{
// Only store the injected services, no further logic
_mobro = mobro;
_scheduler = scheduler;
_settings = settings;
}
public void Init()
{
// Register all items and schedule the recurring tasks
var updateFrequency = _settings.GetValue<int>("update_frequency");
_scheduler.Interval(UpdateMetrics, TimeSpan.FromSeconds(updateFrequency), TimeSpan.Zero);
}
public void Dispose()
{
// Called whenever this plugin instance is discarded
_httpClient.Dispose();
}
private void UpdateMetrics()
{
// Fetch and update the metric values
}
}