123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Runtime.Loader;
- namespace ShakerApp.Tools
- {
- public class PluginsLoader
- {
- private string ext = "";
- private List<Assembly> LoadedAssemblies = new List<Assembly>();
- [AllowNull]
- private AssemblyDependencyResolver resolver;
- private List<string> AllDlls = new List<string>();
- private PluginsLoader()
- {
- }
- public List<T> Load<T>(string path)
- {
- try
- {
- resolver = new AssemblyDependencyResolver(path);
- AssemblyLoadContext.Default.Resolving += Default_Resolving;
- AssemblyLoadContext.Default.ResolvingUnmanagedDll += Default_ResolvingUnmanagedDll;
- AllDlls.Clear();
- AllDlls.AddRange(System.IO.Directory.GetFiles(path, "*.dll", System.IO.SearchOption.AllDirectories));
- var result = AllDlls
- .SelectMany(x =>
- {
- try
- {
- var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(x);
- var types = assembly.GetTypes();
- return types.Where(x => x.GetInterface(typeof(T).FullName!) != null && x.IsAnsiClass && !x.IsAbstract);
- }
- catch
- {
- }
- return new Type[0];
- })
- .Where(x => x != null)
- .Select(x =>
- {
- return (T)Activator.CreateInstance(x!)!;
- })
- .Where(x => x != null)
- .ToList();
- //AssemblyLoadContext.Default.Resolving -= Default_Resolving;
- return result;
- }
- catch
- {
- return new List<T>();
- }
- }
- [DllImport("kernel32.dll")]
- private static extern nint LoadLibrary(string path);
- private nint Default_ResolvingUnmanagedDll(Assembly arg1, string arg2)
- {
- var fileinfo = new FileInfo(arg1.Location);
- if (fileinfo?.Directory == null) return 0;
- string ext = "*.dll";
- var file = fileinfo.Directory.GetFiles(ext, SearchOption.AllDirectories).FirstOrDefault(x=>x.Name == arg2)?.FullName;
-
- if (System.IO.File.Exists(file))
- {
- return LoadLibrary(file);
- }
- throw new NotImplementedException();
- }
- private System.Reflection.Assembly? Default_Resolving(AssemblyLoadContext arg1, System.Reflection.AssemblyName arg2)
- {
- var assembly = AssemblyLoadContext.Default.Assemblies.FirstOrDefault(x => x.FullName == arg2.FullName);
- if (assembly != null) return assembly;
- assembly = LoadedAssemblies.FirstOrDefault(x => x.FullName == arg2.FullName);
- if (assembly != null) return assembly;
- string? path = resolver.ResolveAssemblyToPath(arg2);
- if (!string.IsNullOrEmpty(path))
- {
- assembly = arg1.LoadFromAssemblyPath(path);
- if (assembly != null)
- {
- LoadedAssemblies.Add(assembly);
- return assembly;
- }
- }
- else
- {
- var results = AllDlls.Where(x => x.IndexOf(arg2.Name!) >= 0).ToList();
- results.ForEach(x =>
- {
- try
- {
- var tempassembly = arg1.LoadFromAssemblyPath(x);
- if (tempassembly != null)
- {
- LoadedAssemblies.Add(tempassembly);
- }
- }
- catch
- {
- }
- });
- assembly = LoadedAssemblies.FirstOrDefault(x => x.FullName == arg2.FullName);
- if (assembly != null) return assembly;
- }
- return null;
- }
- static PluginsLoader()
- {
- }
- public static PluginsLoader Defalut { get; } = new PluginsLoader();
- }
- }
|