PluginLoadContext.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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. _resolver = new AssemblyDependencyResolver(pluginPath);
  17. _sharedAssemblies = sharedAssemblies;
  18. _mainLoadContext = mainLoadContext;
  19. }
  20. protected override Assembly? Load(AssemblyName assemblyName)
  21. {
  22. if (assemblyName.Name == null)
  23. return null;
  24. if (_sharedAssemblies.Contains(assemblyName.Name))
  25. return _mainLoadContext.LoadFromAssemblyName(assemblyName);
  26. string? assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
  27. if (assemblyPath != null)
  28. {
  29. // Load in memory to prevent locking the file
  30. using var assemblyFile = File.Open(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read);
  31. string pdbPath = Path.ChangeExtension(assemblyPath, ".pdb");
  32. if (File.Exists(pdbPath))
  33. {
  34. using var pdbFile = File.Open(pdbPath, FileMode.Open, FileAccess.Read, FileShare.Read);
  35. return LoadFromStream(assemblyFile, pdbFile);
  36. }
  37. return LoadFromStream(assemblyFile);
  38. }
  39. return null;
  40. }
  41. protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
  42. {
  43. string? libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
  44. if (libraryPath != null)
  45. return LoadUnmanagedDllFromPath(libraryPath);
  46. return IntPtr.Zero;
  47. }
  48. }
  49. }