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.
After some discussions, we have outlined the following priorities for a plugins rewrite:
IPluginDescriptorwill provideStart()andStop()async methods, which accept a cancellation token.Start()will return aTask<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.A plugin should also implement
IDisposableto help clean up dependencies. Plugin developers may also implementIAsyncDisposableif applicable to them.Plugin lifetime:
Please offer thoughts and ideas. This will be shaped into a proper proposal over time.