using System.Reflection; using MycroForge.Core.Contract; namespace MycroForge.CLI.Commands; public static class Plugins { public static readonly string RootDirectory = Path.Join( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".m4g", "plugins" ); private static readonly List _loaded = []; public static IReadOnlyList Loaded => _loaded; static Plugins() { if (!Directory.Exists(RootDirectory)) { Directory.CreateDirectory(RootDirectory); } } public static List Load() { if (_loaded.Count > 0) return _loaded; var pluginDirectories = Directory .GetDirectories(RootDirectory) .ToArray(); foreach (var directory in pluginDirectories) { var dlls = Directory.GetFiles(directory) .Where(file => file.EndsWith(".dll")) .ToArray(); foreach (var dll in dlls) { var assembly = Assembly.LoadFrom(dll); var plugin = assembly.GetTypes() .Where(IsPluginType) .Select(Activator.CreateInstance) .Cast() .FirstOrDefault(); if (plugin is not null) _loaded.Add(plugin); } } return _loaded; } private static bool IsPluginType(Type type) => type is { IsClass: true, IsAbstract: false } && typeof(ICommandPlugin).IsAssignableFrom(type); }