/// <summary> /// Installs an assembly resolver, which will load *any* assembly which exists recursively within the supplied folder. /// </summary> /// <param name="RootDirectory">The directory to enumerate.</param> public static void InstallRecursiveAssemblyResolver(string RootDirectory) { RefreshAssemblyCache(RootDirectory); AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { // Name is fully qualified assembly definition - e.g. "p4dn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ff968dc1933aba6f" string AssemblyName = args.Name.Split(',')[0]; string AssemblyLocation; if (AssemblyLocationCache.TryGetValue(AssemblyName, out AssemblyLocation)) { // We have this assembly in our folder. if (File.Exists(AssemblyLocation)) { // The assembly still exists, so load it. return(Assembly.LoadFile(AssemblyLocation)); } else { // The assembly no longer exists on disk, so remove it from our cache. AssemblyLocationCache.Remove(AssemblyName); } } // The assembly wasn't found, though may have been compiled or copied as a dependency RefreshAssemblyCache(RootDirectory, string.Format("{0}.dll", AssemblyName)); if (AssemblyLocationCache.TryGetValue(AssemblyName, out AssemblyLocation)) { return(Assembly.LoadFile(AssemblyLocation)); } return(null); }; }
private static void RefreshAssemblyCache(string RootDirectory, string Pattern = "*.dll") { // Initialize our cache of assemblies by enumerating all files in the given folder. foreach (string DiscoveredAssembly in Directory.EnumerateFiles(RootDirectory, Pattern, SearchOption.AllDirectories)) { string AssemblyName = Path.GetFileNameWithoutExtension(DiscoveredAssembly); DateTime AssemblyLastWriteTime = File.GetLastWriteTimeUtc(DiscoveredAssembly); if (AssemblyLocationCache.ContainsKey(AssemblyName)) { // We already have this assembly in our cache. Only replace it if the discovered file is newer (to avoid stale assemblies breaking stuff). if (AssemblyLastWriteTime > AssemblyWriteTimes[AssemblyName]) { AssemblyLocationCache[AssemblyName] = DiscoveredAssembly; AssemblyWriteTimes[AssemblyName] = AssemblyLastWriteTime; } } else { // This is the first copy of this assembly ... add it to our cache. AssemblyLocationCache.Add(AssemblyName, DiscoveredAssembly); AssemblyWriteTimes.Add(AssemblyName, AssemblyLastWriteTime); } } }