PKHeX/PKHeX.WinForms/MainWindow/PluginLoader.cs
Kurt 2b9a105e36 Add unsafe dll load option
ilmerging assemblies somehow ignores the loadFromRemoteSources app
setting, so allow the compiler (user) to specify that the main app
should ignore those security checks.
2018-05-15 20:16:57 -07:00

52 lines
1.8 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace PKHeX.WinForms
{
public static class PluginLoader
{
public static IEnumerable<T> LoadPlugins<T>(string pluginPath)
{
var dllFileNames = Directory.EnumerateFiles(pluginPath, "*.dll", SearchOption.AllDirectories);
var assemblies = GetAssemblies(dllFileNames);
var pluginTypes = GetPluginsOfType<T>(assemblies);
return LoadPlugins<T>(pluginTypes);
}
private static IEnumerable<T> LoadPlugins<T>(IEnumerable<Type> pluginTypes)
{
return pluginTypes.Select(type => (T)Activator.CreateInstance(type));
}
private static IEnumerable<Assembly> GetAssemblies(IEnumerable<string> dllFileNames)
{
#if UNSAFEDLL
return dllFileNames.Select(Assembly.UnsafeLoadFrom);
#else
return dllFileNames.Select(Assembly.LoadFrom);
#endif
}
private static IEnumerable<Type> GetPluginsOfType<T>(IEnumerable<Assembly> assemblies)
{
var pluginType = typeof(T);
foreach (var z in assemblies.Where(z => z != null))
{
Type[] types; try { types = z.GetTypes(); }
catch (Exception ex)
{
Console.WriteLine($"Unable to load plugin [{pluginType.Name}]: {z.FullName}", ex.Message);
continue;
}
foreach (Type type in types)
{
if (type.IsInterface || type.IsAbstract)
continue;
if (type.GetInterface(pluginType.FullName) == null)
continue;
yield return type;
}
}
}
}
}