more load plugins methods

This commit is contained in:
2024-05-02 14:11:57 +02:00
parent c09eb42245
commit 9ffed42e1a

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Net.Http.Headers;
using System.Reflection; using System.Reflection;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text; using System.Text;
@@ -13,6 +14,11 @@ namespace Pilz.Plugins
{ {
private readonly List<TPluginRuntimeInfo> loadedPlugins = []; private readonly List<TPluginRuntimeInfo> loadedPlugins = [];
/// <summary>
/// The default initialization parameters used when no parameters passed. Commonly used for dynamically loading assemblies.
/// </summary>
public object?[] DefaultParameters { get; set; } = [];
/// <summary> /// <summary>
/// Returns a list of all currently loaded plugins. /// Returns a list of all currently loaded plugins.
/// </summary> /// </summary>
@@ -20,7 +26,7 @@ namespace Pilz.Plugins
private void CurrentDomain_AssemblyLoad(object? sender, AssemblyLoadEventArgs args) private void CurrentDomain_AssemblyLoad(object? sender, AssemblyLoadEventArgs args)
{ {
LoadPlugin(args.LoadedAssembly); LoadPlugins(args.LoadedAssembly);
} }
/// <summary> /// <summary>
@@ -50,11 +56,20 @@ namespace Pilz.Plugins
var results = new List<PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo>>(); var results = new List<PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo>>();
foreach (var assembly in assemblies) foreach (var assembly in assemblies)
results.Add(LoadPlugin(assembly, parameters)); results.Add(LoadPlugins(assembly, parameters));
return results; return results;
} }
/// <summary>
/// Loads plugins from already loaded assemblies for the current <see cref="AppDomain.CurrentDomain"/>.
/// </summary>
/// <returns></returns>
public IEnumerable<PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo>> LoadOwnPlugins(params object?[]? parameters)
{
return LoadOwnPlugins(false, parameters);
}
/// <summary> /// <summary>
/// Loads plugins from already loaded assemblies for the current <see cref="AppDomain.CurrentDomain"/>. /// Loads plugins from already loaded assemblies for the current <see cref="AppDomain.CurrentDomain"/>.
/// </summary> /// </summary>
@@ -68,13 +83,13 @@ namespace Pilz.Plugins
AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad; AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad;
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
results.Add(LoadPlugin(assembly, parameters)); results.Add(LoadPlugins(assembly, parameters));
return results; return results;
} }
/// <summary> /// <summary>
/// Loads an assembly from the given file path and then loads the plugin from the assembly. /// Loads an assembly from the given file path and then loads plugins from the assembly.
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
/// <param name="parameters"></param> /// <param name="parameters"></param>
@@ -105,12 +120,12 @@ namespace Pilz.Plugins
} }
/// <summary> /// <summary>
/// Loads the plugin from a given assembly. /// Load plugins from a given assembly.
/// </summary> /// </summary>
/// <param name="assembly"></param> /// <param name="assembly"></param>
/// <param name="parameters"></param> /// <param name="parameters"></param>
/// <returns></returns> /// <returns></returns>
public PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo> LoadPlugin(Assembly assembly, params object?[]? parameters) public PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo> LoadPlugins(Assembly assembly, params object?[]? parameters)
{ {
var result = new PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo> var result = new PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo>
{ {
@@ -122,9 +137,27 @@ namespace Pilz.Plugins
return result; return result;
} }
/// <summary>
/// Loads the plugin from a given type.
/// <br/>Commonly used to ensure loading core plugins.
/// </summary>
/// <typeparam name="TPlugin"></typeparam>
/// <param name="parameters"></param>
/// <returns></returns>
public PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo> LoadPlugin<TPlugin>(params object?[]? parameters) where TPlugin : TPluginInterface
{
var result = new PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo>
{
Assembly = typeof(TPlugin).Assembly
};
LoadPlugin(result, typeof(TPlugin), parameters);
return result;
}
private void LoadPlugin(PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo> result, params object?[]? parameters) private void LoadPlugin(PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo> result, params object?[]? parameters)
{ {
var irmplugin = typeof(TPluginInterface);
if (result.Assembly == null) if (result.Assembly == null)
result.Status = PluginLoadStatus.NoValidPlugin; result.Status = PluginLoadStatus.NoValidPlugin;
@@ -133,32 +166,42 @@ namespace Pilz.Plugins
else else
{ {
foreach (var type in result.Assembly.GetTypes()) foreach (var type in result.Assembly.GetTypes())
{ LoadPlugin(result, type, parameters);
if (irmplugin.IsAssignableFrom(type))
{
var info = Activator.CreateInstance<TPluginRuntimeInfo>();
info.Assembly = result.Assembly;
result.PluginsInternal.Add(info);
try
{
if (Activator.CreateInstance(type, parameters) is TPluginInterface plugin)
{
info.Plugin = plugin;
info.Status = PluginStatus.Success;
loadedPlugins.Add(info);
}
}
catch
{
info.Status = PluginStatus.ErrorAtInitializing;
}
}
}
} }
if (result.PluginsInternal.Count == 0) if (result.PluginsInternal.Count == 0)
result.Status = PluginLoadStatus.NoValidPlugin; result.Status = PluginLoadStatus.NoValidPlugin;
} }
private void LoadPlugin(PluginLoadInfo<TPluginInterface, TPluginRuntimeInfo> result, Type type, params object?[]? parameters)
{
if (parameters == null || parameters.Length == 0)
parameters = DefaultParameters;
if (loadedPlugins.Any(n => n.Plugin != null && n.Plugin.GetType() == type))
result.Status = PluginLoadStatus.AlreadyLoaded;
else if (type.IsAssignableTo(typeof(TPluginInterface)))
{
var info = Activator.CreateInstance<TPluginRuntimeInfo>();
info.Assembly = result.Assembly;
result.PluginsInternal.Add(info);
try
{
if (Activator.CreateInstance(type, parameters) is TPluginInterface plugin)
{
info.Plugin = plugin;
info.Status = PluginStatus.Success;
loadedPlugins.Add(info);
}
}
catch
{
info.Status = PluginStatus.ErrorAtInitializing;
}
}
else
result.Status = PluginLoadStatus.NoValidPlugin;
}
} }
} }