using System.Reflection; using DiunaBI.Infrastructure.Interfaces; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace DiunaBI.Infrastructure.Services; public class PluginManager { private readonly ILogger _logger; private readonly IServiceProvider _serviceProvider; private readonly List _processorTypes = new(); private readonly List _importerTypes = new(); private readonly List _exporterTypes = new(); private readonly List _plugins = new(); public PluginManager(ILogger logger, IServiceProvider serviceProvider) { _logger = logger; _serviceProvider = serviceProvider; } public void LoadPluginsFromDirectory(string pluginsPath) { if (!Directory.Exists(pluginsPath)) { _logger.LogWarning("Plugins directory not found: {Path}", pluginsPath); return; } var dllFiles = Directory.GetFiles(pluginsPath, "*.dll", SearchOption.AllDirectories); foreach (var dllFile in dllFiles) { try { LoadPluginFromAssembly(dllFile); } catch (Exception ex) { _logger.LogError(ex, "Failed to load plugin from {File}", dllFile); } } _logger.LogInformation("Loaded {ProcessorCount} processors, {ImporterCount} importers, and {ExporterCount} exporters from {AssemblyCount} assemblies", _processorTypes.Count, _importerTypes.Count, _exporterTypes.Count, dllFiles.Length); } private void LoadPluginFromAssembly(string assemblyPath) { _logger.LogDebug("Loading assembly from: {Path}", assemblyPath); // Information -> Debug try { var assembly = Assembly.LoadFrom(assemblyPath); _logger.LogDebug("Assembly loaded successfully: {Name}", assembly.FullName); // Information -> Debug foreach (var type in assembly.GetTypes()) { if (typeof(IDataProcessor).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract) { _processorTypes.Add(type); _logger.LogDebug("Registered processor: {Type}", type.Name); // Information -> Debug } if (typeof(IDataImporter).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract) { _importerTypes.Add(type); _logger.LogDebug("Registered importer: {Type}", type.Name); // Information -> Debug } if (typeof(IDataExporter).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract) { _exporterTypes.Add(type); _logger.LogDebug("Registered exporter: {Type}", type.Name); } } } catch (Exception ex) { _logger.LogError(ex, "Failed to load assembly from {Path}", assemblyPath); // ZOSTAW jako Error } } public IDataProcessor? GetProcessor(string processorType) { foreach (var type in _processorTypes) { try { var scope = _serviceProvider.CreateScope(); var instance = (IDataProcessor)ActivatorUtilities.CreateInstance(scope.ServiceProvider, type); if (instance.CanProcess(processorType)) { return instance; } scope.Dispose(); } catch (Exception ex) { _logger.LogError(ex, "Failed to create processor instance of type {Type}", type.Name); } } return null; } public IDataImporter? GetImporter(string importerType) { foreach (var type in _importerTypes) { try { var scope = _serviceProvider.CreateScope(); var instance = (IDataImporter)ActivatorUtilities.CreateInstance(scope.ServiceProvider, type); if (instance.CanImport(importerType)) { return instance; } scope.Dispose(); } catch (Exception ex) { _logger.LogError(ex, "Failed to create importer instance of type {Type}", type.Name); } } return null; } public IDataExporter? GetExporter(string exporterType) { foreach (var type in _exporterTypes) { try { var scope = _serviceProvider.CreateScope(); var instance = (IDataExporter)ActivatorUtilities.CreateInstance(scope.ServiceProvider, type); if (instance.CanExport(exporterType)) { return instance; } scope.Dispose(); } catch (Exception ex) { _logger.LogError(ex, "Failed to create exporter instance of type {Type}", type.Name); } } return null; } public int GetPluginsCount() => _processorTypes.Count + _importerTypes.Count + _exporterTypes.Count; }