cs-codex-dist-tests/DistTestCore/PluginManager.cs

119 lines
3.3 KiB
C#
Raw Normal View History

2023-09-12 08:31:55 +00:00
using FileUtils;
using KubernetesWorkflow;
2023-09-11 14:57:57 +00:00
using Logging;
2023-09-12 09:25:04 +00:00
using System.Reflection;
2023-09-12 08:31:55 +00:00
using Utils;
2023-09-11 14:57:57 +00:00
namespace DistTestCore
{
2023-09-12 08:31:55 +00:00
public class PluginManager
2023-09-11 14:57:57 +00:00
{
private readonly List<IProjectPlugin> projectPlugins = new List<IProjectPlugin>();
2023-09-12 08:31:55 +00:00
public void DiscoverPlugins()
2023-09-11 14:57:57 +00:00
{
2023-09-12 08:31:55 +00:00
projectPlugins.Clear();
var pluginTypes = PluginFinder.GetPluginTypes();
foreach (var pluginType in pluginTypes)
{
var plugin = (IProjectPlugin)Activator.CreateInstance(pluginType)!;
projectPlugins.Add(plugin);
}
2023-09-11 14:57:57 +00:00
}
2023-09-12 08:31:55 +00:00
public void AnnouncePlugins(ILog log)
2023-09-11 14:57:57 +00:00
{
2023-09-12 08:31:55 +00:00
foreach (var plugin in projectPlugins) plugin.Announce(log);
2023-09-11 14:57:57 +00:00
}
2023-09-12 08:31:55 +00:00
public void InitializePlugins(IPluginTools tools)
2023-09-11 14:57:57 +00:00
{
2023-09-12 08:31:55 +00:00
foreach (var plugin in projectPlugins) plugin.Initialize(tools);
2023-09-11 14:57:57 +00:00
}
2023-09-12 08:31:55 +00:00
public void FinalizePlugins(ILog log)
2023-09-11 14:57:57 +00:00
{
2023-09-12 08:31:55 +00:00
foreach (var plugin in projectPlugins) plugin.Finalize(log);
2023-09-11 14:57:57 +00:00
}
2023-09-12 09:25:04 +00:00
public T GetPlugin<T>() where T : IProjectPlugin
{
return (T)projectPlugins.Single(p => p.GetType() == typeof(T));
}
2023-09-12 08:31:55 +00:00
}
public static class PluginFinder
{
private static Type[]? pluginTypes = null;
2023-09-11 14:57:57 +00:00
2023-09-12 08:31:55 +00:00
public static Type[] GetPluginTypes()
2023-09-11 14:57:57 +00:00
{
2023-09-12 08:31:55 +00:00
if (pluginTypes != null) return pluginTypes;
2023-09-11 14:57:57 +00:00
2023-09-12 08:31:55 +00:00
// Reflection can be costly. Do this only once.
2023-09-12 09:25:04 +00:00
FindAndLoadPluginAssemblies();
2023-09-12 08:31:55 +00:00
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
2023-09-12 09:25:04 +00:00
pluginTypes = assemblies.SelectMany(a => a.GetTypes().Where(t =>
typeof(IProjectPlugin).IsAssignableFrom(t) &&
!t.IsAbstract)
).ToArray();
2023-09-12 08:31:55 +00:00
return pluginTypes;
2023-09-11 14:57:57 +00:00
}
2023-09-12 09:25:04 +00:00
private static void FindAndLoadPluginAssemblies()
{
var files = Directory.GetFiles(".");
foreach (var file in files)
{
var f = file.ToLowerInvariant();
if (f.Contains("plugin") && f.EndsWith("dll"))
{
var name = Path.GetFileNameWithoutExtension(file);
try
{
Assembly.Load(name);
}
catch (Exception ex)
{
throw new Exception($"Failed to load plugin from file '{name}'.", ex);
}
}
}
}
2023-09-11 14:57:57 +00:00
}
public interface IProjectPlugin
{
2023-09-12 08:31:55 +00:00
void Announce(ILog log);
void Initialize(IPluginTools tools);
void Finalize(ILog log);
}
public interface IPluginTools : IWorkflowTool, ILogTool, IHttpFactoryTool, IFileTool
{
}
public interface IWorkflowTool
{
IStartupWorkflow CreateWorkflow(string? namespaceOverride = null);
2023-09-11 14:57:57 +00:00
}
2023-09-12 08:31:55 +00:00
public interface ILogTool
2023-09-11 14:57:57 +00:00
{
ILog GetLog();
2023-09-12 08:31:55 +00:00
}
public interface IHttpFactoryTool
{
Http CreateHttp(Address address, string baseUrl, Action<HttpClient> onClientCreated, string? logAlias = null);
Http CreateHttp(Address address, string baseUrl, string? logAlias = null);
}
public interface IFileTool
{
IFileManager GetFileManager();
2023-09-11 14:57:57 +00:00
}
}