diff --git a/Editor/Meta/AssemblyCache.cs b/Editor/Meta/AssemblyCache.cs index be85acb..7fed930 100644 --- a/Editor/Meta/AssemblyCache.cs +++ b/Editor/Meta/AssemblyCache.cs @@ -9,89 +9,12 @@ using UnityEngine; namespace HybridCLR.Editor.Meta { - public class AssemblyCache : IDisposable + public class AssemblyCache : AssemblyCacheBase { - private readonly IAssemblyResolver _assemblyPathResolver; - private readonly ModuleContext _modCtx; - private readonly AssemblyResolver _asmResolver; - private bool disposedValue; - private bool _loadedNetstandard; - public Dictionary LoadedModules { get; } = new Dictionary(); - - public AssemblyCache(IAssemblyResolver assemblyResolver) + public AssemblyCache(IAssemblyResolver assemblyResolver) : base(assemblyResolver) { - _assemblyPathResolver = assemblyResolver; - _modCtx = ModuleDef.CreateModuleContext(); - _asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver; - _asmResolver.EnableTypeDefCache = true; - _asmResolver.UseGAC = false; - } - public ModuleDefMD LoadModule(string moduleName, bool loadReferenceAssemblies = true) - { - // Debug.Log($"load module:{moduleName}"); - if (LoadedModules.TryGetValue(moduleName, out var mod)) - { - return mod; - } - if (moduleName == "netstandard") - { - if (!_loadedNetstandard) - { - LoadNetStandard(); - _loadedNetstandard = true; - } - return null; - } - mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true)); - LoadedModules.Add(moduleName, mod); - - if (loadReferenceAssemblies) - { - foreach (var refAsm in mod.GetAssemblyRefs()) - { - LoadModule(refAsm.Name); - } - } - - return mod; - } - - private void LoadNetStandard() - { - LoadModule("netstandard2.0", false); - LoadModule("netstandard2.1", false); - } - - private ModuleDefMD DoLoadModule(string dllPath) - { - //Debug.Log($"do load module:{dllPath}"); - ModuleDefMD mod = ModuleDefMD.Load(dllPath, _modCtx); - _asmResolver.AddToCache(mod); - return mod; - } - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - foreach(var mod in LoadedModules.Values) - { - mod.Dispose(); - } - LoadedModules.Clear(); - } - disposedValue = true; - } - } - - public void Dispose() - { - Dispose(disposing: true); - GC.SuppressFinalize(this); } } } diff --git a/Editor/Meta/AssemblyCacheBase.cs b/Editor/Meta/AssemblyCacheBase.cs new file mode 100644 index 0000000..82fb007 --- /dev/null +++ b/Editor/Meta/AssemblyCacheBase.cs @@ -0,0 +1,107 @@ +using dnlib.DotNet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HybridCLR.Editor.Meta +{ + public abstract class AssemblyCacheBase : IDisposable + { + private readonly IAssemblyResolver _assemblyPathResolver; + private readonly ModuleContext _modCtx; + private readonly AssemblyResolver _asmResolver; + private bool disposedValue; + private bool _loadedNetstandard; + + public Dictionary LoadedModules { get; } = new Dictionary(); + + private readonly List _loadedModulesIncludeNetstandard = new List(); + + protected AssemblyCacheBase(IAssemblyResolver assemblyResolver) + { + _assemblyPathResolver = assemblyResolver; + _modCtx = ModuleDef.CreateModuleContext(); + _asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver; + _asmResolver.EnableTypeDefCache = true; + _asmResolver.UseGAC = false; + } + + public ModuleDefMD LoadModule(string moduleName, bool loadReferenceAssemblies = true) + { + // Debug.Log($"load module:{moduleName}"); + if (LoadedModules.TryGetValue(moduleName, out var mod)) + { + return mod; + } + if (moduleName == "netstandard") + { + if (!_loadedNetstandard) + { + LoadNetStandard(); + } + return null; + } + mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true)); + LoadedModules.Add(moduleName, mod); + + if (loadReferenceAssemblies) + { + foreach (var refAsm in mod.GetAssemblyRefs()) + { + LoadModule(refAsm.Name); + } + } + + return mod; + } + + private void LoadNetStandard() + { + string netstandardDllPath = _assemblyPathResolver.ResolveAssembly("netstandard", false); + if (!string.IsNullOrEmpty(netstandardDllPath)) + { + DoLoadModule(netstandardDllPath); + } + else + { + DoLoadModule(MetaUtil.ResolveNetStandardAssemblyPath("netstandard2.0")); + DoLoadModule(MetaUtil.ResolveNetStandardAssemblyPath("netstandard2.1")); + } + _loadedNetstandard = true; + } + + private ModuleDefMD DoLoadModule(string dllPath) + { + //Debug.Log($"do load module:{dllPath}"); + ModuleDefMD mod = ModuleDefMD.Load(dllPath, _modCtx); + _asmResolver.AddToCache(mod); + _loadedModulesIncludeNetstandard.Add(mod); + return mod; + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + foreach (var mod in _loadedModulesIncludeNetstandard) + { + mod.Dispose(); + } + _loadedModulesIncludeNetstandard.Clear(); + LoadedModules.Clear(); + } + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/Editor/Meta/AssemblyCacheBase.cs.meta b/Editor/Meta/AssemblyCacheBase.cs.meta new file mode 100644 index 0000000..5c02171 --- /dev/null +++ b/Editor/Meta/AssemblyCacheBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b01fa99119e72141bfee5628c0ffce1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Meta/AssemblyReferenceDeepCollector.cs b/Editor/Meta/AssemblyReferenceDeepCollector.cs index 9d6e80f..44c1c71 100644 --- a/Editor/Meta/AssemblyReferenceDeepCollector.cs +++ b/Editor/Meta/AssemblyReferenceDeepCollector.cs @@ -9,18 +9,10 @@ using UnityEngine; namespace HybridCLR.Editor.Meta { - public class AssemblyReferenceDeepCollector : IDisposable + public class AssemblyReferenceDeepCollector : AssemblyCacheBase { - private readonly IAssemblyResolver _assemblyPathResolver; private readonly List _rootAssemblies; - private readonly ModuleContext _modCtx; - private readonly AssemblyResolver _asmResolver; - private bool disposedValue; - private bool _loadedNetstandard; - - public Dictionary LoadedModules { get; } = new Dictionary(); - public IReadOnlyList GetRootAssemblyNames() { return _rootAssemblies; @@ -41,14 +33,9 @@ namespace HybridCLR.Editor.Meta return _rootAssemblies.Select(ass => LoadedModules[ass]).ToList(); } - public AssemblyReferenceDeepCollector(IAssemblyResolver assemblyResolver, List rootAssemblies) + public AssemblyReferenceDeepCollector(IAssemblyResolver assemblyResolver, List rootAssemblies) : base(assemblyResolver) { - _assemblyPathResolver = assemblyResolver; _rootAssemblies = rootAssemblies; - _modCtx = ModuleDef.CreateModuleContext(); - _asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver; - _asmResolver.EnableTypeDefCache = true; - _asmResolver.UseGAC = false; LoadAllAssembiles(); } @@ -59,67 +46,5 @@ namespace HybridCLR.Editor.Meta LoadModule(asm); } } - - private ModuleDefMD LoadModule(string moduleName) - { - // Debug.Log($"load module:{moduleName}"); - if (LoadedModules.TryGetValue(moduleName, out var mod)) - { - return mod; - } - if (moduleName == "netstandard") - { - if (!_loadedNetstandard) - { - LoadNetStandard(); - _loadedNetstandard = true; - } - return null; - } - mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true)); - LoadedModules.Add(moduleName, mod); - - foreach (var refAsm in mod.GetAssemblyRefs()) - { - LoadModule(refAsm.Name); - } - return mod; - } - - private ModuleDefMD DoLoadModule(string dllPath) - { - //Debug.Log($"do load module:{dllPath}"); - ModuleDefMD mod = ModuleDefMD.Load(dllPath, _modCtx); - _asmResolver.AddToCache(mod); - return mod; - } - - private void LoadNetStandard() - { - DoLoadModule(_assemblyPathResolver.ResolveAssembly("netstandard2.0", true)); - DoLoadModule(_assemblyPathResolver.ResolveAssembly("netstandard2.1", true)); - } - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - foreach(var mod in LoadedModules.Values) - { - mod.Dispose(); - } - } - LoadedModules.Clear(); - disposedValue = true; - } - } - - public void Dispose() - { - Dispose(disposing: true); - GC.SuppressFinalize(this); - } } } diff --git a/Editor/Meta/MetaUtil.cs b/Editor/Meta/MetaUtil.cs index 5b3657d..eb95a7a 100644 --- a/Editor/Meta/MetaUtil.cs +++ b/Editor/Meta/MetaUtil.cs @@ -170,11 +170,14 @@ namespace HybridCLR.Editor.Meta { return new CombinedAssemblyResolver( CreateHotUpdateAssemblyResolver(target, hotUpdateDlls), - CreateAOTAssemblyResolver(target), - new PathAssemblyResolver($"{SettingsUtil.HybridCLRDataPathInPackage}/NetStandard") + CreateAOTAssemblyResolver(target) ); } + public static string ResolveNetStandardAssemblyPath(string assemblyName) + { + return $"{SettingsUtil.HybridCLRDataPathInPackage}/NetStandard/{assemblyName}.dll"; + } public static List CreateDefaultGenericParams(ModuleDef module, int genericParamCount)