Files
HawkeyeVision/VisionBuilder.UI.Common/Plugins/PluginLoader.cs
2025-09-16 10:42:43 +02:00

91 lines
2.8 KiB
C#

using System.Reflection;
using Inspectron.Settings;
using Ninject;
using Serilog;
using VisionBuilder.UI.Common.Attributes;
namespace VisionBuilder.UI.Common.Plugins;
[ModulePriority(1000)]
public class PluginLoader:IVisionBuilderModule
{
const string PLUGINS_DIRECTORY = "Plugins";
public List<IPlugin> Plugins { get; } = new List<IPlugin>();
private bool _isInitialized;
public void InitializeModule()
{
if (_isInitialized)
{
return;
}
_isInitialized = true;
Log.Information("Loading plugins...");
var pluginsPath = Path.Combine("..", "Data", PLUGINS_DIRECTORY);
var enabledPluginsPath = Path.Combine(pluginsPath, "enabled_plugins.txt");
if (!File.Exists(enabledPluginsPath))
{
Log.Warning("Enabled plugins file not found: {EnabledPluginsPath}. All discovered plugins will be disabled by default.", enabledPluginsPath);
File.WriteAllText(enabledPluginsPath, "");
}
List<string> enabledPlugins = File.ReadAllLines(enabledPluginsPath).ToList();
Directory.CreateDirectory(pluginsPath);
var pluginFolders = Directory.GetDirectories(pluginsPath);
foreach (string folder in pluginFolders)
{
var pluginName = Path.GetFileNameWithoutExtension(folder);
if (!enabledPlugins.Contains(pluginName))
{
Log.Information("Skipping plugin {PluginName} as it is not enabled in settings.", pluginName);
continue;
}
var assemblyPath = Path.Combine(folder, Path.GetFileNameWithoutExtension(folder) + ".dll");
if (!File.Exists(assemblyPath))
{
Log.Warning("Plugin assembly not found: {AssemblyPath}", assemblyPath);
continue;
}
try
{
LoadPluginAssembly(assemblyPath);
}
catch (Exception ex)
{
Log.Error(ex, "Failed to load plugin from {AssemblyPath}", assemblyPath);
}
}
Log.Information("Plugin loading completed.");
}
private void LoadPluginAssembly(string assemblyPath)
{
var absPath = Path.GetFullPath(assemblyPath);
var loadContext = new PluginLoadContext(absPath);
var assembly = loadContext.LoadFromAssemblyPath(absPath);
Log.Information("Loaded plugin assembly: {AssemblyName}", assembly.GetName().Name);
foreach (var type in assembly.GetTypes())
{
if (type.IsAssignableTo(typeof(IPlugin)) && !type.IsAbstract)
{
Plugins.Add((IPlugin)Activator.CreateInstance(type));
Log.Information("Loaded plugin: {PluginName}", type.FullName);
}
}
}
}