/// <summary> /// Return a list of found local Assemblies excluding the known assemblies we don't want to scan /// and excluding the ones passed in and excluding the exclusion list filter, the results of this are /// cached for performance reasons. /// </summary> /// <param name="excludeFromResults"> /// An <see cref="IEnumerable{Assembly}"/> to exclude. /// </param> /// <returns>The collection of local assemblies.</returns> internal static HashSet <Assembly> GetAssembliesWithKnownExclusions( IEnumerable <Assembly> excludeFromResults = null) { using (var locker = new UpgradeableReadLock(LocalFilteredAssemblyCacheLocker)) { if (LocalFilteredAssemblyCache.Count > 0) { return(LocalFilteredAssemblyCache); } locker.UpgradeToWriteLock(); foreach (Assembly assembly in GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter)) { LocalFilteredAssemblyCache.Add(assembly); } return(LocalFilteredAssemblyCache); } }
/// <summary> /// Return a list of found local Assemblies excluding the known assemblies we don't want to scan /// and excluding the ones passed in and excluding the exclusion list filter, the results of this are /// cached for performance reasons. /// </summary> /// <param name="excludeFromResults"> /// An <see cref="IEnumerable{Assembly}"/> to exclude. /// </param> /// <returns>The collection of local assemblies.</returns> internal static HashSet<Assembly> GetAssembliesWithKnownExclusions( IEnumerable<Assembly> excludeFromResults = null) { using (UpgradeableReadLock locker = new UpgradeableReadLock(LocalFilteredAssemblyCacheLocker)) { if (LocalFilteredAssemblyCache.Any()) { return LocalFilteredAssemblyCache; } locker.UpgradeToWriteLock(); IEnumerable<Assembly> assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter); foreach (Assembly assembly in assemblies) { LocalFilteredAssemblyCache.Add(assembly); } return LocalFilteredAssemblyCache; } }
/// <summary> /// Lazily loads a reference to all assemblies and only local assemblies. /// This is a modified version of: /// <see href="http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder"/> /// </summary> /// <remarks> /// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been /// loaded in the CLR, not all assemblies. /// See these threads: /// <see href="http://issues.umbraco.org/issue/U5-198"/> /// <see href="http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app"/> /// <see href="http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl"/> /// </remarks> /// <returns> /// The <see cref="HashSet{Assembly}"/>. /// </returns> internal static HashSet<Assembly> GetAllAssemblies() { using (UpgradeableReadLock locker = new UpgradeableReadLock(Locker)) { if (allAssemblies == null) { locker.UpgradeToWriteLock(); try { // NOTE: we cannot use AppDomain.CurrentDomain.GetAssemblies() because this only returns assemblies that have // already been loaded in to the app domain, instead we will look directly into the bin folder and load each one. string binFolder = IOHelper.GetRootDirectoryBinFolder(); List<string> binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList(); HashSet<Assembly> assemblies = new HashSet<Assembly>(); foreach (string file in binAssemblyFiles) { try { AssemblyName assemblyName = AssemblyName.GetAssemblyName(file); assemblies.Add(Assembly.Load(assemblyName)); } catch (Exception ex) { if (ex is SecurityException || ex is BadImageFormatException) { // Swallow exception but allow debugging. Debug.WriteLine(ex.Message); } else { throw; } } } // If for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies. if (!assemblies.Any()) { foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { assemblies.Add(assembly); } } // Here we are trying to get the App_Code assembly string[] fileExtensions = { ".cs", ".vb" }; DirectoryInfo appCodeFolder = new DirectoryInfo(IOHelper.MapPath("~/App_code")); // Check if the folder exists and if there are any files in it with the supported file extensions if (appCodeFolder.Exists && fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())) { Assembly appCodeAssembly = Assembly.Load("App_Code"); if (!assemblies.Contains(appCodeAssembly)) { assemblies.Add(appCodeAssembly); } } // Now set the allAssemblies allAssemblies = new HashSet<Assembly>(assemblies); } catch (InvalidOperationException e) { if (!(e.InnerException is SecurityException)) { throw; } binFolderAssemblies = allAssemblies; } } return allAssemblies; } }
/// <summary> /// Lazily loads a reference to all assemblies and only local assemblies. /// This is a modified version of: /// <see href="http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder"/> /// </summary> /// <remarks> /// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been /// loaded in the CLR, not all assemblies. /// See these threads: /// <see href="http://issues.umbraco.org/issue/U5-198"/> /// <see href="http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app"/> /// <see href="http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl"/> /// </remarks> /// <returns> /// The <see cref="HashSet{Assembly}"/>. /// </returns> internal static HashSet <Assembly> GetAllAssemblies() { using (UpgradeableReadLock locker = new UpgradeableReadLock(Locker)) { if (allAssemblies == null) { locker.UpgradeToWriteLock(); try { // NOTE: we cannot use AppDomain.CurrentDomain.GetAssemblies() because this only returns assemblies that have // already been loaded in to the app domain, instead we will look directly into the bin folder and load each one. string binFolder = IOHelper.GetRootDirectoryBinFolder(); List <string> binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList(); HashSet <Assembly> assemblies = new HashSet <Assembly>(); foreach (string file in binAssemblyFiles) { try { AssemblyName assemblyName = AssemblyName.GetAssemblyName(file); assemblies.Add(Assembly.Load(assemblyName)); } catch (Exception ex) { if (ex is SecurityException || ex is BadImageFormatException || ex is IOException) { // Swallow exception but allow debugging. Debug.WriteLine(ex.Message); } else { throw; } } } // If for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies. if (!assemblies.Any()) { foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { assemblies.Add(assembly); } } // Here we are trying to get the App_Code assembly string[] fileExtensions = { ".cs", ".vb" }; DirectoryInfo appCodeFolder = new DirectoryInfo(IOHelper.MapPath("~/App_code")); // Check if the folder exists and if there are any files in it with the supported file extensions if (appCodeFolder.Exists && fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())) { Assembly appCodeAssembly = Assembly.Load("App_Code"); if (!assemblies.Contains(appCodeAssembly)) { assemblies.Add(appCodeAssembly); } } // Now set the allAssemblies allAssemblies = new HashSet <Assembly>(assemblies); } catch (InvalidOperationException e) { if (!(e.InnerException is SecurityException)) { throw; } binFolderAssemblies = allAssemblies; } } return(allAssemblies); } }