diff options
Diffstat (limited to 'lib/VNLib.Plugins.Extensions.Loading/src')
-rw-r--r-- | lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs | 35 | ||||
-rw-r--r-- | lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs | 40 |
2 files changed, 72 insertions, 3 deletions
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs index 98f8f6c..235aaf6 100644 --- a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs +++ b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs @@ -432,6 +432,41 @@ namespace VNLib.Plugins.Extensions.Loading return (T)CreateService(plugin, exported, null); } + /// <summary> + /// + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="plugin"></param> + /// <param name="instance">The service instance to pass the host</param> + /// <param name="flags">Optional export flags to pass to the host</param> + /// <exception cref="ArgumentNullException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + public static void ExportService<T>(this PluginBase plugin, T instance, ExportFlags flags = ExportFlags.None) + where T : class => ExportService(plugin, typeof(T), instance, flags); + + /// <summary> + /// Exports a service of the desired type to the host application. Once the plugin + /// is done loading, the host will be able to access the service instance. + /// <para> + /// You should avoid mutating the service instance after the plugin has been + /// loaded, especially if you are using factory methods to create the service. + /// </para> + /// </summary> + /// <param name="plugin"></param> + /// <param name="type">The service type to export</param> + /// <param name="instance">The service instance to pass the host</param> + /// <param name="flags">Optional export flags to pass to the host</param> + /// <exception cref="ArgumentNullException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + public static void ExportService(this PluginBase plugin, Type type, object instance, ExportFlags flags = ExportFlags.None) + { + ArgumentNullException.ThrowIfNull(plugin, nameof(plugin)); + plugin.ThrowIfUnloaded(); + + //Init new service wrapper + ServiceExport export = new(type, instance, flags); + plugin.Services.Add(export); + } /// <summary> /// <para> diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs b/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs index 1061dda..c0f39d7 100644 --- a/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs +++ b/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Plugins.Extensions.Loading @@ -28,6 +28,7 @@ using System.Reflection; using System.Collections.Generic; using System.Runtime.CompilerServices; +using VNLib.Plugins.Essentials.Runtime; using VNLib.Plugins.Extensions.Loading.Events; namespace VNLib.Plugins.Extensions.Loading.Routing @@ -39,7 +40,7 @@ namespace VNLib.Plugins.Extensions.Loading.Routing public static class RoutingExtensions { private static readonly ConditionalWeakTable<IEndpoint, PluginBase?> _pluginRefs = new(); - + private static readonly ConditionalWeakTable<PluginBase, EndpointCollection> _pluginEndpoints = new(); /// <summary> /// Constructs and routes the specific endpoint type for the current plugin @@ -147,6 +148,32 @@ namespace VNLib.Plugins.Extensions.Loading.Routing } /// <summary> + /// Routes a single endpoint for the current plugin and exports the collection to the + /// service pool + /// </summary> + /// <param name="plugin"></param> + /// <param name="endpoint">The endpoint to add to the collection</param> + public static void Route(this PluginBase plugin, IEndpoint endpoint) + { + /* + * Export the new collection to the service pool in the constructor + * function to ensure it's only export once per plugin + */ + static EndpointCollection OnCreate(PluginBase plugin) + { + EndpointCollection collection = new(); + plugin.ExportService<IVirtualEndpointDefinition>(collection); + return collection; + } + + //Get the endpoint collection for the current plugin + EndpointCollection endpoints = _pluginEndpoints.GetValue(plugin, OnCreate); + + //Add the endpoint to the collection + endpoints.Endpoints.Add(endpoint); + } + + /// <summary> /// Gets the plugin that loaded the current endpoint /// </summary> /// <param name="ep"></param> @@ -200,6 +227,13 @@ namespace VNLib.Plugins.Extensions.Loading.Routing plugin.ScheduleInterval(interval.Item2, interval.Item1.Interval); } } - + + private sealed class EndpointCollection : IVirtualEndpointDefinition + { + public List<IEndpoint> Endpoints { get; } = new(); + + ///<inheritdoc/> + IEnumerable<IEndpoint> IVirtualEndpointDefinition.GetEndpoints() => Endpoints; + } } } |