AssemblyCache.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using dnlib.DotNet;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using UnityEngine;
  9. namespace HybridCLR.Editor.Meta
  10. {
  11. public class AssemblyCache : IDisposable
  12. {
  13. private readonly IAssemblyResolver _assemblyPathResolver;
  14. private readonly ModuleContext _modCtx;
  15. private readonly AssemblyResolver _asmResolver;
  16. private bool disposedValue;
  17. public Dictionary<string, ModuleDefMD> LoadedModules { get; } = new Dictionary<string, ModuleDefMD>();
  18. public AssemblyCache(IAssemblyResolver assemblyResolver)
  19. {
  20. _assemblyPathResolver = assemblyResolver;
  21. _modCtx = ModuleDef.CreateModuleContext();
  22. _asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver;
  23. _asmResolver.EnableTypeDefCache = true;
  24. _asmResolver.UseGAC = false;
  25. }
  26. public ModuleDefMD LoadModule(string moduleName, bool loadReferenceAssemblies = true)
  27. {
  28. // Debug.Log($"load module:{moduleName}");
  29. if (LoadedModules.TryGetValue(moduleName, out var mod))
  30. {
  31. return mod;
  32. }
  33. mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true));
  34. LoadedModules.Add(moduleName, mod);
  35. if (loadReferenceAssemblies)
  36. {
  37. foreach (var refAsm in mod.GetAssemblyRefs())
  38. {
  39. LoadModule(refAsm.Name);
  40. }
  41. }
  42. return mod;
  43. }
  44. private ModuleDefMD DoLoadModule(string dllPath)
  45. {
  46. //Debug.Log($"do load module:{dllPath}");
  47. ModuleDefMD mod = ModuleDefMD.Load(dllPath, _modCtx);
  48. _asmResolver.AddToCache(mod);
  49. return mod;
  50. }
  51. protected virtual void Dispose(bool disposing)
  52. {
  53. if (!disposedValue)
  54. {
  55. if (disposing)
  56. {
  57. foreach(var mod in LoadedModules.Values)
  58. {
  59. mod.Dispose();
  60. }
  61. LoadedModules.Clear();
  62. }
  63. disposedValue = true;
  64. }
  65. }
  66. public void Dispose()
  67. {
  68. Dispose(disposing: true);
  69. GC.SuppressFinalize(this);
  70. }
  71. }
  72. }