using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using SlpModularCms.Core.Modules; namespace SlpModularCms.Core.Hosting; /// /// Orkestrator die modules ontdekt en hun lifecycle beheert. /// public class ModuleOrchestrator { private readonly List _modules = new(); private readonly ILogger _logger; public ModuleOrchestrator(ILogger logger) { _logger = logger; } /// /// Names of the modules discovered on this instance (e.g. so the frontend can tell /// a master-only feature apart from a slave instance without that module loaded). /// public IReadOnlyList ModuleNames => _modules.Select(m => m.Name).ToArray(); public void DiscoverModules() { _logger.LogInformation("Start module discovery..."); // Forceer het laden van module assemblies van disk var path = AppDomain.CurrentDomain.BaseDirectory; var moduleFiles = Directory.GetFiles(path, "SlpModularCms.Modules.*.dll"); foreach (var file in moduleFiles) { try { var assemblyName = AssemblyName.GetAssemblyName(file); if (AppDomain.CurrentDomain.GetAssemblies().All(a => a.FullName != assemblyName.FullName)) { Assembly.Load(assemblyName); _logger.LogDebug("Assembly geladen: {AssemblyName}", assemblyName.Name); } } catch (Exception ex) { _logger.LogWarning(ex, "Kon assembly niet laden van disk: {FilePath}", file); } } var assemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => a.FullName != null && a.FullName.StartsWith("SlpModularCms.Modules")) .ToList(); foreach (var assembly in assemblies) { var moduleTypes = assembly.GetTypes() .Where(t => typeof(IModule).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract); foreach (var type in moduleTypes) { try { if (Activator.CreateInstance(type) is IModule module) { _modules.Add(module); _logger.LogInformation("Module ontdekt: {ModuleName} v{Version}", module.Name, module.Version); } } catch (Exception ex) { _logger.LogError(ex, "Fout bij het instantiƫren van module type {TypeName}", type.FullName); } } } _logger.LogInformation("{Count} modules succesvol geladen.", _modules.Count); } public void RegisterModuleServices(IServiceCollection services) { foreach (var module in _modules) { try { module.RegisterServices(services); _logger.LogInformation("Services geregistreerd voor module: {ModuleName}", module.Name); } catch (Exception ex) { _logger.LogError(ex, "Fout bij het registreren van services voor module {ModuleName}", module.Name); } } } public void UseModules(IApplicationBuilder app) { foreach (var module in _modules) { try { module.UseModule(app); _logger.LogInformation("Module geactiveerd in pipeline: {ModuleName}", module.Name); } catch (Exception ex) { _logger.LogError(ex, "Fout bij het activeren van module {ModuleName} in de pipeline", module.Name); } } } }