/// <summary> /// Attempts to find and load an <see cref="Assembly"/> when the requesting <see cref="Assembly"/> /// is known. /// </summary> /// <remarks> /// This method differs from <see cref="ResolveForUnknownRequestor(string)"/> in a couple of ways. /// First, we only attempt to handle the load if the requesting assembly is one we've loaded. /// If it isn't one of ours, then presumably some other component is hooking <see cref="AppDomain.AssemblyResolve"/> /// and will have a better idea of how to load the assembly. /// Second, we only look immediately next to the requesting assembly, instead of next to all the assemblies /// we've previously loaded. An analyzer needs to ship with all of its dependencies, and if it doesn't we don't /// want to mask the problem. /// </remarks> private static Assembly ResolveForKnownRequestor(string requestedAssemblyName, Assembly requestingAssembly) { lock (s_guard) { string requestingAssemblyName = requestingAssembly.FullName; string requestingAssemblyFullPath; if (!s_filesFromAssemblyNames.TryGetValue(requestingAssemblyName, out requestingAssemblyFullPath)) { // The requesting assembly is not one of ours; don't try to satisfy the request. return(null); } string nameWithPolicyApplied = AppDomain.CurrentDomain.ApplyPolicy(requestedAssemblyName); Assembly assembly; if (s_assembliesFromNames.TryGetValue(nameWithPolicyApplied, out assembly)) { // We've already loaded an assembly by this name; use that. return(assembly); } AssemblyIdentity assemblyIdentity; if (!AssemblyIdentity.TryParseDisplayName(nameWithPolicyApplied, out assemblyIdentity)) { return(null); } string directoryPath = Path.GetDirectoryName(requestingAssemblyFullPath); string assemblyFullPath = AssemblyPathHelper.GetCandidatePath(directoryPath, assemblyIdentity); if (!File.Exists(assemblyFullPath)) { return(null); } assembly = LoadCore(assemblyFullPath); s_requestingFilesFromFiles[assemblyFullPath] = requestingAssemblyFullPath; return(assembly); } }
/// <summary> /// Attempts to find and load an <see cref="Assembly"/> when the requesting <see cref="Assembly"/> /// is unknown. /// </summary> /// <remarks> /// In this case we simply look next to all the assemblies we have previously loaded for one with the /// correct name and a matching <see cref="AssemblyIdentity"/>. /// </remarks> private static Assembly ResolveForUnknownRequestor(string requestedAssemblyName) { lock (s_guard) { string requestedNameWithPolicyApplied = AppDomain.CurrentDomain.ApplyPolicy(requestedAssemblyName); Assembly assembly; if (s_assembliesFromNames.TryGetValue(requestedNameWithPolicyApplied, out assembly)) { // We've already loaded an assembly by this name; use that. return(assembly); } AssemblyIdentity requestedAssemblyIdentity; if (!AssemblyIdentity.TryParseDisplayName(requestedNameWithPolicyApplied, out requestedAssemblyIdentity)) { return(null); } foreach (string loadedAssemblyFullPath in s_assembliesFromFiles.Keys) { string directoryPath = Path.GetDirectoryName(loadedAssemblyFullPath); string candidateAssemblyFullPath = AssemblyPathHelper.GetCandidatePath(directoryPath, requestedAssemblyIdentity); AssemblyIdentity candidateAssemblyIdentity = TryGetAssemblyIdentity(candidateAssemblyFullPath); if (requestedAssemblyIdentity.Equals(candidateAssemblyIdentity)) { return(LoadCore(candidateAssemblyFullPath)); } } return(null); } }