PluginLoadContext.cs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Reflection;
  5. using System.Runtime.Loader;
  6. namespace GodotPlugins
  7. {
  8. public class PluginLoadContext : AssemblyLoadContext
  9. {
  10. private readonly AssemblyDependencyResolver _resolver;
  11. private readonly ICollection<string> _sharedAssemblies;
  12. private readonly AssemblyLoadContext _mainLoadContext;
  13. public PluginLoadContext(string pluginPath, ICollection<string> sharedAssemblies,
  14. AssemblyLoadContext mainLoadContext)
  15. {
  16. Console.WriteLine(pluginPath);
  17. Console.Out.Flush();
  18. _resolver = new AssemblyDependencyResolver(pluginPath);
  19. _sharedAssemblies = sharedAssemblies;
  20. _mainLoadContext = mainLoadContext;
  21. }
  22. protected override Assembly? Load(AssemblyName assemblyName)
  23. {
  24. if (assemblyName.Name == null)
  25. return null;
  26. if (_sharedAssemblies.Contains(assemblyName.Name))
  27. return _mainLoadContext.LoadFromAssemblyName(assemblyName);
  28. string? assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
  29. if (assemblyPath != null)
  30. {
  31. // Load in memory to prevent locking the file
  32. using var assemblyFile = File.Open(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read);
  33. string pdbPath = Path.ChangeExtension(assemblyPath, ".pdb");
  34. if (File.Exists(pdbPath))
  35. {
  36. using var pdbFile = File.Open(pdbPath, FileMode.Open, FileAccess.Read, FileShare.Read);
  37. return LoadFromStream(assemblyFile, pdbFile);
  38. }
  39. return LoadFromStream(assemblyFile);
  40. }
  41. return null;
  42. }
  43. protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
  44. {
  45. string? libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
  46. if (libraryPath != null)
  47. return LoadUnmanagedDllFromPath(libraryPath);
  48. return IntPtr.Zero;
  49. }
  50. }
  51. }