using Microsoft.Extensions.Logging; using StellaOps.Integrations.Contracts; using StellaOps.Integrations.Core; using StellaOps.Plugin; using StellaOps.Plugin.Hosting; using System.Reflection; namespace StellaOps.Integrations.WebService; /// /// Loads and manages integration connector plugins. /// public sealed class IntegrationPluginLoader { private readonly ILogger? _logger; private readonly List _plugins = []; public IntegrationPluginLoader(ILogger? logger = null) { _logger = logger; } /// /// Gets all loaded plugins. /// public IReadOnlyList Plugins => _plugins; /// /// Discovers and loads integration connector plugins from the specified directory. /// public IReadOnlyList LoadFromDirectory( string pluginDirectory, string searchPattern = "StellaOps.Integrations.Plugin.*.dll") { if (!Directory.Exists(pluginDirectory)) { _logger?.LogWarning("Plugin directory does not exist: {Directory}", pluginDirectory); return []; } var options = new PluginHostOptions { PluginsDirectory = pluginDirectory, EnsureDirectoryExists = false, RecursiveSearch = false }; options.SearchPatterns.Add(searchPattern); var result = PluginHost.LoadPlugins(options); var loadedPlugins = new List(); foreach (var pluginAssembly in result.Plugins) { var connectorPlugins = PluginLoader.LoadPlugins(new[] { pluginAssembly.Assembly }); loadedPlugins.AddRange(connectorPlugins); foreach (var plugin in connectorPlugins) { _logger?.LogDebug("Loaded integration connector plugin: {Name} ({Provider}) from {Assembly}", plugin.Name, plugin.Provider, pluginAssembly.Assembly.GetName().Name); } } _plugins.AddRange(loadedPlugins); return loadedPlugins; } /// /// Loads integration connector plugins from the specified assemblies. /// public IReadOnlyList LoadFromAssemblies(IEnumerable assemblies) { var loadedPlugins = PluginLoader.LoadPlugins(assemblies); _plugins.AddRange(loadedPlugins); return loadedPlugins; } /// /// Gets a plugin by provider. /// public IIntegrationConnectorPlugin? GetByProvider(IntegrationProvider provider) { return _plugins.FirstOrDefault(p => p.Provider == provider); } /// /// Gets all plugins for a given type. /// public IReadOnlyList GetByType(IntegrationType type) { return _plugins.Where(p => p.Type == type).ToList(); } /// /// Gets all available plugins (checking IsAvailable). /// public IReadOnlyList GetAvailable(IServiceProvider services) { return _plugins.Where(p => { try { return p.IsAvailable(services); } catch { return false; } }).ToList(); } }