Redesigned the DiscordBotCore by splitting it into multiple projects. Created a WebUI and preparing to remove the DiscordBot application
This commit is contained in:
81
DiscordBotCore.PluginManagement.Loading/Loader.cs
Normal file
81
DiscordBotCore.PluginManagement.Loading/Loader.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using System.Reflection;
|
||||
using DiscordBotCore.PluginCore;
|
||||
using DiscordBotCore.PluginCore.Interfaces;
|
||||
using DiscordBotCore.PluginManagement.Loading.Exceptions;
|
||||
|
||||
namespace DiscordBotCore.PluginManagement.Loading;
|
||||
|
||||
internal class Loader
|
||||
{
|
||||
internal delegate void FileLoadedHandler(string fileName, Exception exception);
|
||||
internal delegate void PluginLoadedHandler(PluginLoaderResult result);
|
||||
|
||||
internal event FileLoadedHandler? OnFileLoadedException;
|
||||
internal event PluginLoadedHandler? OnPluginLoaded;
|
||||
|
||||
private readonly IPluginManager _pluginManager;
|
||||
|
||||
internal Loader(IPluginManager manager)
|
||||
{
|
||||
_pluginManager = manager;
|
||||
}
|
||||
|
||||
internal async Task Load()
|
||||
{
|
||||
var installedPlugins = await _pluginManager.GetInstalledPlugins();
|
||||
var files = installedPlugins.Where(plugin => plugin.IsEnabled).Select(plugin => plugin.FilePath).ToArray();
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly.LoadFrom(file);
|
||||
}
|
||||
catch
|
||||
{
|
||||
OnFileLoadedException?.Invoke(file, new Exception($"Failed to load plugin from file {file}"));
|
||||
}
|
||||
}
|
||||
|
||||
await LoadEverythingOfType<IDbEvent>();
|
||||
await LoadEverythingOfType<IDbCommand>();
|
||||
await LoadEverythingOfType<IDbSlashCommand>();
|
||||
}
|
||||
|
||||
private Task LoadEverythingOfType<T>()
|
||||
{
|
||||
var types = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(s => s.GetTypes())
|
||||
.Where(p => typeof(T).IsAssignableFrom(p) && !p.IsInterface);
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var plugin = (T?)Activator.CreateInstance(type);
|
||||
|
||||
if (plugin is null)
|
||||
{
|
||||
throw new Exception($"Failed to create instance of plugin with type {type.FullName} [{type.Assembly}]");
|
||||
}
|
||||
|
||||
PluginLoaderResult result = plugin switch
|
||||
{
|
||||
IDbEvent @event => PluginLoaderResult.FromIDbEvent(@event),
|
||||
IDbCommand command => PluginLoaderResult.FromIDbCommand(command),
|
||||
IDbSlashCommand command => PluginLoaderResult.FromIDbSlashCommand(command),
|
||||
_ => PluginLoaderResult.FromException(new PluginNotFoundException($"Unknown plugin type {plugin.GetType().FullName}"))
|
||||
};
|
||||
|
||||
OnPluginLoaded?.Invoke(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnPluginLoaded?.Invoke(PluginLoaderResult.FromException(ex));
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user