示例#1
0
            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));
                }
            }