122 lines
4.3 KiB
C#
122 lines
4.3 KiB
C#
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using SQLVision.Core.Enums;
|
|
using SQLVision.Core.Interfaces;
|
|
using SQLVision.Core.Models;
|
|
using System.Reflection;
|
|
|
|
namespace SQLVision.Services.Services;
|
|
|
|
public class PluginManager : IPluginManager
|
|
{
|
|
private readonly ILogger<PluginManager> _logger;
|
|
private readonly IServiceProvider _serviceProvider;
|
|
private readonly List<ISqlVisionPlugin> _plugins = new();
|
|
|
|
public PluginManager(ILogger<PluginManager> logger, IServiceProvider serviceProvider)
|
|
{
|
|
_logger = logger;
|
|
_serviceProvider = serviceProvider;
|
|
}
|
|
|
|
public void LoadPlugins(string pluginsDirectory)
|
|
{
|
|
if (!Directory.Exists(pluginsDirectory))
|
|
{
|
|
Directory.CreateDirectory(pluginsDirectory);
|
|
_logger.LogInformation("Created plugins directory: {Directory}", pluginsDirectory);
|
|
return;
|
|
}
|
|
|
|
var pluginFiles = Directory.GetFiles(pluginsDirectory, "*.dll");
|
|
_logger.LogInformation("Found {Count} plugin files", pluginFiles.Length);
|
|
|
|
foreach (var pluginFile in pluginFiles)
|
|
{
|
|
try
|
|
{
|
|
var assembly = Assembly.LoadFrom(pluginFile);
|
|
var pluginTypes = assembly.GetTypes()
|
|
.Where(t => typeof(ISqlVisionPlugin).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
|
|
|
|
foreach (var pluginType in pluginTypes)
|
|
{
|
|
try
|
|
{
|
|
var plugin = (ISqlVisionPlugin)Activator.CreateInstance(pluginType)!;
|
|
var context = new PluginContext(_serviceProvider);
|
|
plugin.InitializeAsync(context).Wait();
|
|
_plugins.Add(plugin);
|
|
_logger.LogInformation("Loaded plugin: {Name} v{Version}", plugin.Name, plugin.Version);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to initialize plugin from type {Type}", pluginType.FullName);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to load plugin from {File}", pluginFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
public IEnumerable<ISqlVisionPlugin> GetPlugins() => _plugins.AsReadOnly();
|
|
|
|
public T? GetPlugin<T>() where T : ISqlVisionPlugin
|
|
=> _plugins.OfType<T>().FirstOrDefault();
|
|
|
|
public async Task BeforeExecutionAsync(ScriptMetadata script, Dictionary<string, object> parameters)
|
|
{
|
|
foreach (var plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
await plugin.InitializeAsync(new PluginContext(_serviceProvider));
|
|
// TODO: Добавить метод BeforeExecution в ISqlVisionPlugin если нужно
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in plugin {Plugin} BeforeExecution", plugin.Name);
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task AfterExecutionAsync(ScriptMetadata script, ExecutionResult result)
|
|
{
|
|
foreach (var plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
// TODO: Добавить метод AfterExecution в ISqlVisionPlugin если нужно
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in plugin {Plugin} AfterExecution", plugin.Name);
|
|
}
|
|
}
|
|
}
|
|
|
|
private class PluginContext : IPluginContext
|
|
{
|
|
public IServiceProvider ServiceProvider { get; }
|
|
public IConfiguration Configuration { get; }
|
|
public ILogger Logger { get; }
|
|
|
|
public PluginContext(IServiceProvider serviceProvider)
|
|
{
|
|
ServiceProvider = serviceProvider;
|
|
Configuration = serviceProvider.GetRequiredService<IConfiguration>();
|
|
Logger = serviceProvider.GetRequiredService<ILogger<PluginManager>>();
|
|
}
|
|
|
|
public Task ShowNotificationAsync(string message, NotificationType type)
|
|
{
|
|
// TODO: Реализовать показ уведомлений через UI
|
|
Logger.LogInformation("Plugin notification ({Type}): {Message}", type, message);
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
} |