Skip to content

[Discussion] Plugin Remaster #4

@TheBrambleShark

Description

@TheBrambleShark

After some discussions, we have outlined the following priorities for a plugins rewrite:

  • Plugin Constructed using DI.
  • IPluginDescriptor will provide Start() and Stop() async methods, which accept a cancellation token.
    • Start() will return a Task<Result>. A successful result indicates that tree initialization can continue. A failed result will abort initializing any child plugins which have a Required relationship.
    • Stop() will return void. A plugin must always be prepared to stop at any time.
  • Each plugin will get its own ScopedServiceProvider.
  • Plugins should be able to be reloaded (which stops and disposes all plugins and plugin scopes, then reloads all plugins).
  • Plugins should be able to be registered at runtime though a reload of the full plugin tree.
public interface IPluginDescriptor
{
    /// <summary>
    /// Gets the name of the plugin. This name should be unique.
    /// </summary>
    string Name { get; }

    /// <summary>
    /// Gets the description of the plugin.
    /// </summary>
    string Description { get; }

    /// <summary>
    /// Gets the version of the plugin.
    /// </summary>
    Version Version { get; }

    /// <summary>
    /// Called when the application host is ready to start the plugin.
    /// </summary>
    Task<Result> StartAsync(CancellationToken ct = default);

    /// <summary>
    /// Called when the application host is shutting down the plugin.
    /// </summary>
    /// <remarks>
    /// A plugin must be prepared to stop at any time.
    /// </remarks>
    Task StopAsync();

A plugin should also implement IDisposable to help clean up dependencies. Plugin developers may also implement IAsyncDisposable if applicable to them.

Plugin lifetime:

  • Load plugins (handles referenced assemblies being missing)
  • Service registrations - No ordering required
  • StartAsync() - Might require some ordering
  • Runtime (handling notifications/requests/direct service calls). Main application's runtime takes over.
  • StopAsync()
  • Dispose()/DisposeAsync()

Please offer thoughts and ideas. This will be shaped into a proper proposal over time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions