public async Task <PEFile?> ResolveAsync(IAssemblyReference reference) { PEFile?module; // 0) if we're inside a package, look for filename.dll in parent directories if (providedAssemblyResolver != null) { module = await providedAssemblyResolver.ResolveAsync(reference).ConfigureAwait(false); if (module != null) { return(module); } } string tfm = await tfmTask.ConfigureAwait(false); bool isWinRT = reference.IsWindowsRuntime; string key = tfm + ";" + (isWinRT ? reference.Name : reference.FullName); // 1) try to find exact match by tfm + full asm name in loaded assemblies var lookup = LazyInit.VolatileRead(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName); if (lookup == null) { lookup = await CreateLoadedAssemblyLookupAsync(shortNames : isWinRT).ConfigureAwait(false); lookup = LazyInit.GetOrSet(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName, lookup); } if (lookup.TryGetValue(key, out module)) { referenceLoadInfo.AddMessageOnce(reference.FullName, MessageKind.Info, "Success - Found in Assembly List"); return(module); } string?file = parent.GetUniversalResolver().FindAssemblyFile(reference); if (file != null) { // Load assembly from disk LoadedAssembly?asm; if (loadOnDemand) { asm = assemblyList.OpenAssembly(file, isAutoLoaded: true); } else { asm = assemblyList.FindAssembly(file); } if (asm != null) { referenceLoadInfo.AddMessage(reference.ToString(), MessageKind.Info, "Success - Loading from: " + file); return(await asm.GetPEFileOrNullAsync().ConfigureAwait(false)); } return(null); } else { // Assembly not found; try to find a similar-enough already-loaded assembly var candidates = new List <(LoadedAssembly assembly, Version version)>(); foreach (LoadedAssembly loaded in alreadyLoadedAssemblies) { module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false); var reader = module?.Metadata; if (reader == null || !reader.IsAssembly) { continue; } var asmDef = reader.GetAssemblyDefinition(); var asmDefName = reader.GetString(asmDef.Name); if (reference.Name.Equals(asmDefName, StringComparison.OrdinalIgnoreCase)) { candidates.Add((loaded, asmDef.Version)); } } if (candidates.Count == 0) { referenceLoadInfo.AddMessageOnce(reference.ToString(), MessageKind.Error, "Could not find reference: " + reference); return(null); } candidates.SortBy(c => c.version); var bestCandidate = candidates.FirstOrDefault(c => c.version >= reference.Version).assembly ?? candidates.Last().assembly; referenceLoadInfo.AddMessageOnce(reference.ToString(), MessageKind.Info, "Success - Found in Assembly List with different TFM or version: " + bestCandidate.fileName); return(await bestCandidate.GetPEFileOrNullAsync().ConfigureAwait(false)); } }
public async Task <PEFile?> ResolveAsync(IAssemblyReference reference) { PEFile?module; // 0) if we're inside a package, look for filename.dll in parent directories if (providedAssemblyResolver != null) { module = await providedAssemblyResolver.ResolveAsync(reference).ConfigureAwait(false); if (module != null) { return(module); } } string tfm = await tfmTask.ConfigureAwait(false); // 1) try to find exact match by tfm + full asm name in loaded assemblies module = await alreadyLoadedAssemblies.TryGetModuleAsync(reference, tfm).ConfigureAwait(false); if (module != null) { referenceLoadInfo.AddMessageOnce(reference.FullName, MessageKind.Info, "Success - Found in Assembly List"); return(module); } string?file = parent.GetUniversalResolver(applyWinRTProjections).FindAssemblyFile(reference); if (file != null) { // Load assembly from disk LoadedAssembly?asm; if (loadOnDemand) { asm = assemblyList.OpenAssembly(file, isAutoLoaded: true); } else { asm = assemblyList.FindAssembly(file); } if (asm != null) { referenceLoadInfo.AddMessage(reference.FullName, MessageKind.Info, "Success - Loading from: " + file); return(await asm.GetPEFileOrNullAsync().ConfigureAwait(false)); } return(null); } else { // Assembly not found; try to find a similar-enough already-loaded assembly module = await alreadyLoadedAssemblies.TryGetSimilarModuleAsync(reference).ConfigureAwait(false); if (module == null) { referenceLoadInfo.AddMessageOnce(reference.FullName, MessageKind.Error, "Could not find reference: " + reference.FullName); } else { referenceLoadInfo.AddMessageOnce(reference.FullName, MessageKind.Info, "Success - Found in Assembly List with different TFM or version: " + module.FileName); } return(module); } }