コード例 #1
0
        private Assembly AssemblyResolve(object sender, ResolveEventArgs args)
        {
            string fullName = args.Name;
            string simpleName;

            if (!AssemblyIdentity.TryParseSimpleName(fullName, out simpleName))
            {
                return(null);
            }

            if (args.RequestingAssembly != null)
            {
                string originalDllPath = null, originalExePath = null;

                string originalPath = null;
                lock (ReferencesLock)
                {
                    LoadedAssembly loadedAssembly;
                    if (loadedAssemblies.TryGetValue(args.RequestingAssembly, out loadedAssembly))
                    {
                        originalPath = loadedAssembly.OriginalPath;

                        string pathWithoutExtension = Path.Combine(Path.GetDirectoryName(originalPath), simpleName);
                        originalDllPath = pathWithoutExtension + ".dll";
                        originalExePath = pathWithoutExtension + ".exe";

                        Assembly assembly;
                        if (loadedAssembliesByPath.TryGetValue(originalDllPath, out assembly) || loadedAssembliesByPath.TryGetValue(originalExePath, out assembly))
                        {
                            return(assembly);
                        }
                    }
                }

                // if the referring assembly is already loaded by our loader, load from its directory:
                if (originalPath != null)
                {
                    // Copy & load both .dll and .exe, this is not a common scenario we would need to optimize for.
                    // Remember both loaded assemblies for the next time, even though their versions might not match the current request
                    // they might match the next one and we don't want to load them again.
                    Assembly dll = ShadowCopyAndLoadDependency(originalDllPath);
                    Assembly exe = ShadowCopyAndLoadDependency(originalExePath);

                    if (dll == null ^ exe == null)
                    {
                        return(dll ?? exe);
                    }

                    if (dll != null && exe != null)
                    {
                        // .dll and an .exe of the same name might have different versions,
                        // one of which might match the requested version.
                        // Prefer .dll if they are both the same.
                        return(FindHighestVersionOrFirstMatchingIdentity(fullName, new[] { dll, exe }));
                    }
                }
            }

            return(GetOrLoadKnownAssembly(fullName, simpleName));
        }