using System.Reflection; using System.Runtime.Loader; using IdentityShroud.PluginSupport; namespace IdentityShroud.Core.Plugins; public static class PluginLoader { public static IEnumerable LoadPlugins(string pluginsFolder) { if (!Directory.Exists(pluginsFolder)) yield break; foreach (var dll in Directory.EnumerateFiles(pluginsFolder, "*.dll")) { foreach (var plugin in LoadPluginDll(dll)) yield return plugin; } } private static IEnumerable LoadPluginDll(string dll) { Assembly asm; try { asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.GetFullPath(dll)); } catch { yield break; } IEnumerable pluginTypes; try { pluginTypes = asm.GetTypes() .Where(t => typeof(IPlugin).IsAssignableFrom(t) && t is { IsInterface: false, IsAbstract: false }); } catch { yield break; } foreach (var t in pluginTypes) { IPlugin? instance = null; try { instance = (IPlugin?)Activator.CreateInstance(t); } catch { // ignore bad plugin types } if (instance != null) yield return instance; } } }